1

我正在使用带有 boost 线程、锁互斥锁和所有好东西的 c++。

两个线程 A 和 B。A 是一个网络线程,其中有来自客户端的信息来回传递。B 是一个带有变量的工作者,它需要是线程安全的。

A类有多个线程,B类只是一个线程。A 的实例将被添加到 B 的作业列表中,并且 A 将锁定直到 B 完成任务。(作业的线程安全列表工作正常)

A 将作业添加到 B 然后锁定,但在大多数情况下,在 A 锁定之前。B 将处理该作业并在 A 应用锁之前(尝试)释放锁。导致As死锁。

我不确定我应该在这里做什么。我可以发布代码,但我想在概念上更容易讨论。

4

2 回答 2

1

您似乎在应该使用条件的地方使用锁。引用boost 文档

这些类condition_variablecondition_variable_any一个线程提供了一种机制,以等待来自另一个线程的特定条件已变为真的通知。

这听起来像你试图用锁做的事情。

于 2012-09-01T13:14:47.877 回答
1

实际问题在于 B 获取任务并在来自 A 的线程锁定之前开始执行它。您观察到的结果可以归类为“错过通知”。在尝试使用互斥锁或其他简单同步器实现双向同步时,经常发生这种情况。

您必须确保 B 不会通知,除非 A 已经在等待,或者您可以确保不会错过通知。

虽然第一种方法可能很难执行,但后者非常简单:使用信号量(或手动重置事件或 (...))。

关于信号量:

  • 线程 A 想要将作业放入队列
  • 线程 A 创建一个 COUNT=ZERO 和 MAX=1 的信号量
  • 线程 A 以某种方式将信号量添加到作业中
  • 线程 A 将作业放入队列
  • 线程 A 等待信号量
  • 线程 A 销毁信号量

尽管:

  • 线程 B 观察队列
  • 线程 B 得到任务
  • 线程 B 执行任务
  • 线程 B 解锁信号量 ONCE

请注意,如果计数,信号量 UNLOCK 是非阻塞的

除了使用信号量,您还可以使用手动设置/重置的事件。只需让 A 创建并锁定关闭的事件,然后让 B 将其设置为 ON。

于 2012-09-01T13:18:46.033 回答