我的问题是我有多个线程,它们存储在某个容器中,我需要知道某个位置的线程何时完成。 在Windows上,我会做类似的事情:
HANDLE handles[3];
//handles were initialized
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE)
有没有办法用std :: thread实现相同的效果?
答案 0 :(得分:6)
据我所知,标准库中没有任何内容支持等待这种性质。标准库建立在底层操作系统线程支持之上。必要时,标准库只能提供最低的公分母功能。这意味着它无法包装Win32线程库提供的一些更丰富的功能。
答案 1 :(得分:3)
只需使用std::condition_variable
,即可让线程在完成之前触发notify_all()
或notify_one()
。
然后执行您需要cv.wait()
电话的WaitForMultipleObjects()
。
答案 2 :(得分:2)
这是一个如何使用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));
请参阅live example
答案 3 :(得分:1)
尝试Async++ Composition,这是N3428 C ++标准提案的参考实现。
在此之前,本文是相关的:
以不可移植的方式,您也可以致电std::thread::native_handle()使用WaitForMultipleObjects
返回。
答案 4 :(得分:-1)
你想要的是与boost :: thread_group相同的东西。
不存在,但您可以编写该功能:std :: vector和std :: for_each在每个元素上调用join()/ WaitForSingleObject,或者当然搜索像{一样执行相同操作的第三方{3}}