如何等待几个 std::threads
Posted
技术标签:
【中文标题】如何等待几个 std::threads【英文标题】:How to wait for several std::threads 【发布时间】:2016-03-03 15:59:44 【问题描述】:基于这个问题:Timeout for thread.join()(ManuelAtWork 的回答)我尝试为我的 std::threads 实现超时:
std::vector<std::shared_ptr<TestFlow>> testFlowObjects;
std::thread workerThreads[MAX_PARALLEL_NR]; // maximum of 32 threads
std::vector<std::future<void>> helperThreads;
for(int readerCounter=0; readerCounter<GetNumberOfReader(); readerCounter++)
testFlowObjects.push_back(std::make_shared<TestFlow>(m_logFiles));
testFlowObjects.back()->SetThreadID(readerCounter);
testFlowObjects.back()->SetTestResults(m_testResultsVector); // vector of int
workerThreads[readerCounter] = std::thread(&TestFlow::DoWork, testFlowObjects.back());
// wait for all threads
for(int threadCount=0; threadCount<GetNumberOfReader(); threadCount++)
// use helper threads to be able to join with timeout
helperThreads.push_back(std::async(std::launch::async, &std::thread::join, &workerThreads[threadCount]));
helperThreads.back().wait_for(std::chrono::seconds(5)); // 5 sec
如果我使用连接而不是 std::future 辅助线程代码,它可以正常工作,但我不能等待无限!
使用 std::future 方法,似乎并非所有线程都已完成,我得到了:R6010: abort() has been called
任何想法如何正确地做到这一点?
我想我必须像这样改变它:
if(helperThreads.back().wait_for(std::chrono::seconds(5)) == std::future_status::timeout) // WHAT SHOULD I DO HERE???
【问题讨论】:
我猜这不是你说的版本?你在哪里加入你的workerThreads?期货的目的是什么? 展示一个完整的例子。你加入了工作线程吗?为什么要在循环中等待 5 秒,这有什么意义?这意味着您甚至在启动下一个任务之前都要等待。当然,您要启动所有任务,然后等待它们。当你只等待std::future
对象时,你为什么要问等待std::thread
?
@JonathanWakely 如果我加入线程,它会等到线程完成,但我必须在定义的时间后退出(5 秒仅用于测试 -> 没有任何实际意义)你读过 ManuelAtWork 的答案吗?他的方法使用辅助线程来完成工作线程,但我必须使其适应多个线程(看我的示例)!
@Superlokkus 你读过这个问题吗?一切都被描述了,我不明白你为什么反对它?! (发布更多代码没有帮助)
但是你在循环中执行helperThreads.back().wait_for(std::chrono::seconds(5));
inside,所以你启动一个新线程等待更早的线程,然后等待 5 秒,然后启动另一个线程,然后等待5 秒,然后启动另一个线程,然后等待 5 秒……这意味着您总共等待 5 x GetNumberOfReader 秒!您是否查看了其他问题的已接受答案?
【参考方案1】:
简而言之和推荐
您发布的方法(ManuelAtWork 的回答)是一种变通方法,使用 std::future
的等待通信语义作为在 std::thread::join
上等待超时的方法。这也可以通过 条件变量 的通信来实现,正如所提到的公认答案。
但是,为什么要在单独的 std::thread
中开始 ThreadFunc
呢?只需使用std::async
,它将返回一个未来,它将执行您的ThreadFunc
i.e。 TestFlow::DoWork
。
您可能会因为尝试加入不可加入的线程而中止,或者因为您没有在该位置加入一些明确的(移动新线程时,在旧std::thread
的析构函数中)
workerThreads[readerCounter] = std::thread(&TestFlow::DoWork, testFlowObjects.back());
背景/问题
如果您仍想使用std::thread
,您必须自己进行线程之间的通信和等待。这意味着许多类型的任务和问题(停止、加入、等待、线程池)。
您链接的解决方法假设您有一些其他方法可以终止线程。 (通过沟通)
【讨论】:
以上是关于如何等待几个 std::threads的主要内容,如果未能解决你的问题,请参考以下文章