Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if thread has finished work in C++11 and above?

How can I check if thread has finished work in C++11 and above? I have been reading the documentation and I have written the following code:

#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 tells only that the thread has started work, but I would like to know how to write code to check if the thread has finished work.

For example:

#include <iostream>
#include <thread>
void mythread() 
{
    //do some stuff
}
int main() 
{
  std::thread foo(mythread);  
  if (foo.finishedWork())
  {
    foo.join();
    //do some next stuff
  }
}
like image 272
user2856064 Avatar asked Feb 23 '17 14:02

user2856064


Video Answer


2 Answers

You may want to use std::future, it provides higher level facilities where you can trivially check if the asynchronous computation is finished (aka ready): Example:

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
    }
}

On the other hand, you may think simply using a "safe" (or atomic) flag works:

#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();
}

But, it doesn't work. While you think is_done = true is the last thing you did in mythread(); You may have created some objects of automatic storage duration in that scope, and since such objects are destroyed in the reverse order of construction, there will still be "some work" in that thread after setting is_done.

like image 161
WhiZTiM Avatar answered Oct 03 '22 23:10

WhiZTiM


You want a future. Start your thread withstd::async and use wait_for with zero seconds on it. Compare the result against future_status::ready.

like image 31
knivil Avatar answered Oct 04 '22 01:10

knivil