我正在设计一个带有服务器的程序,让两个客户端进行通信。有一个客户端执行命令,另一个客户端执行命令。
为了使这项工作,我有两个线程:一个用于受控客户端的线程,另一个用于控制器客户端。
受控客户端始终保持连接状态,具有包含任务的向量,并在添加任务时执行这些任务。它有一个无限的while循环,当连接关闭时会停止。
控制器 - 客户端将任务添加到矢量。
现在由于两个线程之间共享一个向量,可能会出现争用情况,但由于一个线程只添加对象而另一个只弹出对象,这是必要的吗?我试图用这个问题制作流程图,但也许不清楚。我真的不知道如何创建流程图:
我正在使用C ++中的std::vector <CustomClass>
来实现这一点。
提前致谢,
ief2
编辑:其他问题:vector.size()
来电是否需要互斥?
答案 0 :(得分:7)
是的,这需要一个互斥锁。
同时执行的 vector.pop_front()
和vector.push_back()
会产生各种混乱 - 假设非标准vector.pop_front()
执行名称所暗示的内容。
旁注:使用队列或列表而不是向量
答案 1 :(得分:3)
您应该控制对向量的访问。你不想尝试同时推送和弹出。
答案 2 :(得分:1)
是的,你需要一个互斥锁。在多处理器机器上,两个线程可能同时尝试推送和弹出。一个条件变量来指示何时有待处理的东西也是一个好主意。
答案 3 :(得分:1)
我想知道受控客户端是如何实现的。它是一个不断检查任务队列的循环吗?如果是这种情况并且您认为效率更重要,则可以将任务队列实现为单链接列表,并且仍然具有线程安全且无锁定的实现。您只需要列表中的一个哑节点,头部指向这个哑节点。空列表表示为哑节点的下一个字段为空。弹出时,只需将头部从当前哑节点移动到下一个节点,该节点将成为新的哑节点。当你按下时,你只需附加任务,因为列表不为空(至少包含一个哑节点)。这仅适用于双线程场景。
答案 4 :(得分:0)
STL容器不是安全的。所以是的,你需要一个锁定机制(即互斥锁)来使容器线程安全。
您可以阅读this SO question以查看包装STL队列以获得线程安全的示例。
答案 5 :(得分:0)
流程图通常不是一个好主意。
需要同步。在多个线程中插入或删除std::vector
并不安全。
如果你一个线程推送而另一个线程同时弹出会发生什么,但是push会导致向量的内部数组被重新分配?弹出线程正在访问一些可能不再使用的内存。
如果一个线程正在读取而另一个线程正在推送,则会发生类似的情况。如果推送导致向量重新分配,则读取现在正在访问很可能不再有效的内存。
答案 6 :(得分:0)
不,您不需要互斥锁,但需要进行某种同步。我建议不要使用无限定时循环,而是使用事件。如果生成器已完成对共享集合的写入,则让生成器发出信号,并在完成读取命令时让消费者发出信号(不要在阻止生成器写入的情况下开始执行命令)。
这会停止在空向量中检查命令的无用CPU周期。