这个模型需要互斥体吗?

发布于 2024-11-04 21:20:34 字数 543 浏览 1 评论 0原文

我正在设计一个带有服务器的程序,让两个客户端进行通信。有一个客户端执行命令,另一个客户端让另一个客户端执行命令。

为了完成这项工作,我有两个线程:一个线程用于受控客户端,另一个线程用于控制器客户端。

受控客户端始终保持连接,具有包含任务的向量,并在添加任务时执行这些任务。它有一个无限的 while 循环,当连接关闭时该循环停止。

控制器-客户端将任务添加到向量中。

现在,由于两个线程之间共享一个向量,因此可能会发生竞争条件,但由于一个线程仅添加对象,而另一个线程仅弹出对象,因此有必要吗?我试图制作一个流程图来解决这个问题,但也许还不清楚。我真的不知道如何创建流程图: 在此处输入图像描述

我正在使用 C++ 中的 std::vector意识到这一点。

预先感谢,
ief2

编辑:附加问题:vector.size() 调用是否需要互斥锁?

I'm designing a program with a server that let's two clients communicate. There's one client that executes commands and another that makes the other client execute them.

To make this work, I have two threads: one thread for the controlled-client, another for the controller-client.

The controlled-client always stays connected, has a vector with tasks and executes these tasks if a task is added. It has an infinite while loop which is stopped when the connection is closed.

The controller-client adds tasks to the vector.

Now since there is an vector shared between two threads a race condition may occur, but since one thread only adds objects and the other only pops objects, is that necessary? I tried to make a flowchart with this problem, but maybe it isn't clear. I don't really know how to create a flowchart:
enter image description here

I'm using std::vector <CustomClass> from C++ to realize this.

Thanks in advance,
ief2

EDIT: Additional Question: Does the vector.size() call need a mutex?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

吲‖鸣 2024-11-11 21:20:34

是的,这需要一个互斥体。

vector.pop_front()vector.push_back() 同时执行会造成各种混乱 - 假设非标准 vector.pop_front() code> 的作用正如其名称所暗示的那样。

旁注:使用队列或列表而不是向量

Yes, this needs a mutex.

vector.pop_front() and vector.push_back() executing at the same time would create all sorts of mess - assuming the nonstandard vector.pop_front() does what the name implies.

Side note: use a queue or a list rather than a vector

背叛残局 2024-11-11 21:20:34

您应该控制对向量的访问。您不想尝试同时推送和弹出。

You should control access to the vector. You don't want to be trying to push and pop simultaneously.

霞映澄塘 2024-11-11 21:20:34

是的,你需要一个互斥体。在多处理器计算机上,两个线程可能会同时尝试推送和弹出。使用条件变量来指示何时需要处理某些内容可能也是一个好主意。

Yes you need a mutex. On a multiple processor machine both threads could be trying to push and pop at the same time. A condition variable to indicate when there is something to process might be a good idea too.

心在旅行 2024-11-11 21:20:34

我想知道受控客户端是如何实现的。是不是一个循环不断的检查任务队列?如果是这样,并且您认为效率更重要,您可以将任务队列实现为单链表,并且仍然具有线程安全和无锁的实现。您所需要的只是列表中的一个哑节点,并且头指向这个哑节点。空列表表示哑节点的下一个字段为空。当你弹出时,你只需将头从当前的哑节点移动到下一个节点,该节点将成为新的哑节点。当您推送时,您只需追加任务,因为列表不为空(至少包含一个哑节点)。这只适用于双线程场景。

I'm wondering how the controlled-client is implemented. Is it a loop that keeps checking the task queue? If it is the case and you believe that efficiency is more important, you can implement the task queue as a singly-linked list and still have a thread-safe and lock-free implementation. All you need is a dumb node in the list and the head is pointed to this dumb node. The empty list is represented as the dumb node's next field is null. When you pop, you just move the head from the current dumb node to the next node which becomes the new dumb node. When you push, you just append the task, since the list is not empty(contains at least a dumb node). This only works for two-thread scenario.

我也只是我 2024-11-11 21:20:34

STL 容器不是线程安全的。所以,是的,您需要一个锁定机制(即互斥体)来使容器线程安全。

您可以阅读这个SO问题来查看包装STL队列的示例线程安全。

STL containers are not thred-safe. So yes you need a locking mechanism (i.e a mutex) to make the container thread-safe.

You may read this SO question to see an example for wrapping an STL queue for thread-safety.

猥︴琐丶欲为 2024-11-11 21:20:34

流程图通常不是一个好主意。

需要同步。在多个线程中从 std::vector 插入或删除是不安全的。

如果一个线程同时推送而另一个线程弹出,但推送导致向量的内部数组被重新分配,会发生什么情况?弹出线程正在访问一些可能不再使用的内存。

如果一个线程正在读取而另一个线程正在推送,则可能会发生类似的情况。如果推送导致向量重新分配,则读取现在访问的内存很可能不再有效。

Flow charts usually aren't a good idea.

Synchronization is required. Inserting or erasing from an std::vector in multiple threads is not safe.

What happens if you one thread pushes and the other thread pops at the same time, but the push causes the vector's internal array to be reallocated? The popping thread is accessing some memory that's possibly no longer in use.

A similar situation can occur if one thread is reading and the other thread is pushing. If the push causes the vector to reallocate, the read is now accessing memory that's most likely no longer valid.

猫腻 2024-11-11 21:20:34

不,您不需要互斥锁,但某种同步是必要的。我建议不要使用无限定时循环,而是使用事件。如果生产者已完成对共享集合的写入,则让其发出信号;当消费者完成读取命令时,让其发出信号(在阻止生产者写入时不要开始执行命令)。

这会停止检查空向量中命令的无用 CPU 周期。

No you don't need a mutex, but some kind of synchronisation is necessary. I would recommend not using infinite timed loops, and would use events instead. Have the producer signal if it has finished writing to the shared collection, and have the consumer signal when it is finished reading the commands (don't start executing the commands while preventing the producer from writing).

This stop useless CPU cycles of checking for commands in an empty vector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文