简体   繁体   中英

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

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 .

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

You can use wait_for of std::future to check whether the result is already there. A simple way to get a future for an asynchronous task is 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...

I had the same problem, and my solution was to wrap the thread class, so I can set a flag when the function has finished its work.

Here you find the discussion for the solution Stack Overflow

And here is the working example: Celma managed thread

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM