【问题标题】:WaitForMultipleObjects alternative with std::thread?用 std::thread 替代 WaitForMultipleObjects?
【发布时间】:2014-02-23 21:03:27
【问题描述】:

我的问题是我有多个线程,它们存储在某个容器中,我需要知道某个位置的线程何时完成。 在 Windows 上,我会执行以下操作:

HANDLE handles[3];
//handles were initialized
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE)

有什么办法可以用std::thread达到同样的效果吗?

【问题讨论】:

  • @marcin_j 这个问题不仅仅是提供信息,它可以说是对这个问题的彻底欺骗(或者说它是相反的)。感谢您链接它。对于 OP 来说,不,如果没有您的一些工作,就不是天生的。这种任意的线程退出检测不在线程支持库中,至少我从未见过。
  • 如果您在 Windows 上并希望保持更多 C++ 风格,那么 Concurrency Runtime 是一个不错的选择。 Microsoft 的 std::thread 和 std::async 实现是在 VS2013 的基础上构建的。

标签: c++ multithreading stl


【解决方案1】:

据我所知,标准库中没有任何内容支持这种等待。标准库建立在底层操作系统线程支持之上。标准库必然只能提供最低公分母功能。这意味着它无法封装 Win32 线程库提供的一些更丰富的功能。

【讨论】:

    【解决方案2】:

    只需使用std::condition_variable 并让您的线程在完成之前触发notify_all() 或notify_one()。

    然后在您希望拨打WaitForMultipleObjects() 的地方拨打cv.wait()。

    【讨论】:

    • 这不是问题的答案,因为 std::condition_variable 允许通知一个或多个等待线程有关特定对象(特别是特定线程)的状态。 WaitForMultipleObjects() 允许一个线程被通知多个线程中多个对象的状态。
    【解决方案3】:

    试试Async++ Composition,它是N3428 C++ 标准提案的参考实现。

    这篇文章在此之前是相关的:

    Broken promises–C++0x futures

    以一种不可移植的方式,您还可以调用std::thread::native_handle() 以使用WaitForMultipleObjects 与返回。

    【讨论】:

      【解决方案4】:

      如果您愿意让主线程在轮询线程的就绪状态时休眠(或者您可以让专用线程处理等待),那么这里有一个示例,说明如何使用 std::thread 和 std::future 实现相同的效果)。

      考虑一下这个函数,将一系列迭代器放入std::future的容器中,这将阻塞直到至少一个任务完成:

      const int TIME_BETWEEN_POLLS_MS = 50;
      
      // Wait (sleep) between polls until a task is finished then return iterator to future.
      template <typename Iterator>
      Iterator waitForFirst(Iterator first, Iterator last) {
          auto it = first;
          auto status = std::future_status::timeout;
          while (status != std::future_status::ready) {
              if (++it == last) { // Rotate in range.
                  it = first;
              }
              status = it->wait_for(std::chrono::milliseconds(TIME_BETWEEN_POLLS_MS));
          }
          return it;
      }
      

      现在,如果您有一个期货容器 (std::future) 与在不同线程上运行的任务的返回值相关联,您可以简单地使用函数 waitForFirst 获取一个指向未来的迭代器,该迭代器首先获得其结果.

          // Lets say you have a vector of futures, e.g.
          std::vector<std::future<std::thread::id>> futures;
      
          /* Push futures to vector... */
      
          // Block until first task is finished.
          // 'it' is iterator to future associated with result.
          auto it = waitForFirst(std::begin(futures), std::end(futures));
      

      见live example

      【讨论】:

        【解决方案5】:

        你想要的是相当于 boost::thread_group 的东西。

        不存在,但您可以编写该功能:一个 std::vector 和 std::for_each 在每个元素上调用 join()/WaitForSingleObject,或者当然搜索像 @ 一样的第 3 方987654321@

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-09
          • 2020-12-15
          • 2020-12-21
          • 2014-01-10
          • 1970-01-01
          相关资源
          最近更新 更多