【问题标题】:How to wait for a thread to join only if it has been started仅当线程已启动时如何等待线程加入
【发布时间】:2016-11-01 08:53:16
【问题描述】:

我有两个事件被两个事件处理程序触发和处理。 在EventHandler2 中启动boost::thread。 在 EventHandler2 中,应用程序通过调用 join() 来等待该线程完成。

这在快速计算机上运行良好,因为启动线程的事件总是首先被触发,然后是导致应用程序等待join() 的另一个事件。 但是,在旧机器上,事件以不同的顺序触发(因为在调用 EventHandler2 之前需要完成一些繁重的计算)。 所以EventHandler1首先被调用并且不等待,因为join()立即返回(线程还没有启动,因为第二个事件没有被触发)。 我在这里能做的最好的事情是什么?在调用join() 之前是否需要锁定一个互斥锁,然后等待它。这样,我可以确保在调用 join() 之前启动线程。 在这种情况下使用的最佳模式是什么? 谢谢!

【问题讨论】:

标签: c++ multithreading boost-thread


【解决方案1】:

您似乎需要指定执行顺序或优先级。从您的问题来看,您似乎也有异构线程(在行为方面),所以我将建议同步。单独的mutex 可能还不够(尽管在许多实现中,互斥锁与二进制信号量相同)。一个简单的方法是使用监视器。 https://en.wikipedia.org/wiki/Monitor_(synchronization)

【讨论】:

    【解决方案2】:

    解释问题(如果我误解了请告诉我):您有两个将要执行的事件处理程序(A 和 B),但不能保证先执行哪一个 - 执行顺序可能是 (A,B) 也可能是 (B,A)... 但在任何一种情况下,您都希望系统的行为 好像 处理程序已在 (A,B ) 顺序。

    我解决这个问题的方法是让处理程序更智能,以便他们可以检测到“错误”处理程序何时首先执行并优雅地处理它。特别是,当您的 B 处理程序执行时,它应该有一种方法来检测 A 处理程序是否已经执行。如果 B 看到 A 已经执行,那么 B 可以做正常的事情(即 join() 线程),一切都很好。另一方面,如果 B 发现 A 还没有执行,那么 B 应该设置一个标志(也许是 A 可以访问的数据结构中的布尔值?),这样当 A 处理程序稍后运行时,它会知道 B 处理程序已经过去了,因此 A 会知道它不能依赖 B 进行任何清理工作。即A运行时会检查flag;如果标志是由 B 设置的,那么 A 也会在返回之前调用 join() ,因为 A 知道 B 以后不会这样做(或者,如果您不想调用,也许 A 可以安排另一个 B 事件join() 直接来自 A 处理程序)。

    如果您的 A 和 B 处理程序都在同一个线程中被调用,那么这应该很简单;如果从不同的线程调用 A 和 B,则需要更加小心地以线程安全的方式进行标志处理(例如使用 std::atomic 或类似方式)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 2011-10-11
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      相关资源
      最近更新 更多