我的问题是我有多个线程,它们存储在某个容器中,我需要知道某个位置的线程何时完成。 在Windows上我会做类似的事情:
HANDLE handles[3];
//handles were initialized
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE)
有没有办法用std :: thread实现相同的效果?
我的问题是我有多个线程,它们存储在某个容器中,我需要知道某个位置的线程何时完成。 在Windows上我会做类似的事情:
HANDLE handles[3];
//handles were initialized
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE)
有没有办法用std :: thread实现相同的效果?
据我所知,标准库中没有任何东西支持等待这种性质。标准库建立在底层操作系统线程支持之上。必要时,标准库只能提供最低的公分母功能。这意味着它无法包装Win32线程库提供的一些更丰富的功能。
只需使用一个 std::condition_variable
让你的线程开火 notify_all()
要么 notify_one()
就在他们完成之前。
然后做 cv.wait()
你想要的地方 WaitForMultipleObjects()
呼叫。
这是一个如何使用实现相同效果的示例 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 = finishingThread(std::begin(futures), std::end(futures));
看到 实例
尝试 异步++组合 这是一个参考实现 N3428 C ++标准提案。
在此之前,本文是相关的:
以不可移植的方式,你也可以打电话 的std ::螺纹::函数native_handle() 使用 WaitForMultipleObjects
随着回归。
你想要的是与boost :: thread_group相当的东西。
不存在,但您可以编写该功能:std :: vector和std :: for_each在每个元素上调用join()/ WaitForSingleObject,或者当然搜索执行相同操作的第三方 cppthreadpool