如何检查线程是否已在C ++ 11及更高版本中完成工作?

时间:2017-02-23 14:20:30

标签: c++ multithreading c++11 multitasking

如何检查线程是否已在C ++ 11及更高版本中完成工作?我一直在阅读文档,我写了以下代码:

#include <iostream>
#include <thread>
void mythread() 
{
    //do some stuff
}
int main() 
{
  std::thread foo(mythread);  
  if (foo.joinable())
  {
    foo.join();
    //do some next stuff
  }
}

joinable只告诉线程已经开始工作,但我想知道如何编写代码来检查线程是否已完成工作。

例如:

#include <iostream>
#include <thread>
void mythread() 
{
    //do some stuff
}
int main() 
{
  std::thread foo(mythread);  
  if (foo.finishedWork())
  {
    foo.join();
    //do some next stuff
  }
}

4 个答案:

答案 0 :(得分:5)

您可能希望使用std::future,它提供了更高级别的工具,您可以轻松检查异步计算是否已完成(也就是准备好):示例:

void mythread() {
    //do some stuff
}

template<typename T>
bool future_is_ready(std::future<T>& t){
    return t.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}

int main() 
{
    std::future<void> foo = std::async(std::launch::async, mythread);  
    if (future_is_ready(foo)){
        //do some next stuff
    }
}

另一方面,您可能只想使用&#34; safe&#34; (或原子)旗帜有效:

#include <iostream>
#include <thread>

std::atomic<bool> is_done{false};

void mythread() 
{
    //do some stuff
    ......
    is_done = true;
}
int main() 
{
  std::thread foo(mythread);  
  if (is_done)
  {
    foo.join();
    //do some next stuff
  }
  .....
  if(foo.joinable()) foo.join();
}

但是,它不起作用。虽然您认为is_done = true是您在mythread()中做的最后一件事;您可能在该范围内创建了一些自动存储持续时间的对象,并且由于这些对象以相反的构造顺序被销毁,因此仍然会有一些工作&#34;在设置is_done之后的那个帖子中。

答案 1 :(得分:1)

你想要一个未来。使用std::async启动您的主题,并使用wait_for并使用零秒。将结果与future_status::ready进行比较。

答案 2 :(得分:1)

您可以使用wait_forstd::future来检查结果是否已存在。获得异步任务未来的一种简单方法是std::async

#include <future>

// ...

// launch task and get result future
auto rf = std::async(std::launch::async, mythread);
// get initial status
auto status = rf.wait_for(std::chrono::nanoseconds(1));
// loop while task is not ready
while(status != std::future_status::ready)
{ 

    // not ready yet, do other stuff here

    // 1 nanosecond timeout check
    status = rf.wait_for(std::chrono::nanoseconds(1));
}
// we are done...

答案 3 :(得分:0)

我有同样的问题,我的解决方案是包装线程类,所以我可以在函数完成其工作时设置一个标志。

在这里,您可以找到解决方案Stack Overflow

的讨论

以下是工作示例:Celma managed thread