Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timeout for thread.join()

Tags:

c++

c++11

Is it possible to set a timeout for a call to std::thread::join()? I want to handle the case in which the thread is taking too long to run, or terminate the thread. I may be doing this for multiple threads (say, up to 30).

Preferably without boost, but I'd be interested in a boost solution if that's the best way.

like image 456
ty. Avatar asked Mar 30 '12 18:03

ty.


People also ask

Does join method accept a timeout?

To handle these situations, we use overloaded versions of the join() method that allow us to specify a timeout period. Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.” Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.”

What is thread join () in threading?

Join() Blocks the calling thread until the thread represented by this instance terminates, while continuing to perform standard COM and SendMessage pumping. Join(Int32)

What does thread join () do in Python?

A thread can be joined in Python by calling the Thread. join() method. This has the effect of blocking the current thread until the target thread that has been joined has terminated.

How do you Timeout a thread in Python?

Applying timeout function using thread in PythonThe first thread is to execute the function. 2. The second thread is to measure the time taken by the function. The only second thread should whether the time is over or not.


2 Answers

There is no timeout for std::thread::join(). However you can view std::thread::join() as merely a convenience function. Using condition_variables you can create very rich communication and cooperation between your threads, including timed waits. For example:

#include <chrono> #include <thread> #include <iostream>  int thread_count = 0; bool time_to_quit = false; std::mutex m; std::condition_variable cv;  void f(int id) {     {     std::lock_guard<std::mutex> _(m);     ++thread_count;     }     while (true)     {         {         std::lock_guard<std::mutex> _(m);         std::cout << "thread " << id << " working\n";         }         std::this_thread::sleep_for(std::chrono::milliseconds(250));         std::lock_guard<std::mutex> _(m);         if (time_to_quit)             break;     }     std::lock_guard<std::mutex> _(m);     std::cout << "thread ended\n";     --thread_count;     cv.notify_all(); }  int main() {     typedef std::chrono::steady_clock Clock;     std::thread(f, 1).detach();     std::thread(f, 2).detach();     std::thread(f, 3).detach();     std::thread(f, 4).detach();     std::thread(f, 5).detach();     auto t0 = Clock::now();     auto t1 = t0 + std::chrono::seconds(5);     std::unique_lock<std::mutex> lk(m);     while (!time_to_quit && Clock::now() < t1)         cv.wait_until(lk, t1);     time_to_quit = true;     std::cout << "main ending\n";     while (thread_count > 0)         cv.wait(lk);     std::cout << "main ended\n"; } 

In this example main launches several threads to do work, all of which occasionally check if it is time to quit under a mutex (this could also be an atomic). The main thread also monitors if it is time to quit (if the threads get all their work done). If main runs out of patience, he just declares it to be time to quit, then waits for all threads to perform any necessary clean up before exiting.

like image 150
Howard Hinnant Avatar answered Oct 04 '22 04:10

Howard Hinnant


Yes, it is possible. The solution that has been suggested by Galik looks like this:

#include <thread> #include <future> ... // Launch the thread. std::thread thread(ThreadFnc, ...); ... // Terminate the thread. auto future = std::async(std::launch::async, &std::thread::join, &thread); if (future.wait_for(std::chrono::seconds(5))      == std::future_status::timeout) {    /* --- Do something, if thread has not terminated within 5 s. --- */  } 

However, this essentially launches a third thread that performs the thread.join().

(Note: The destructor of future will block until thread has joined and the auxiliary thread has terminated.)


Maybe launching a thread just to bring another thread down is not what you want. There is another, portable solution without an auxiliary thread:

#include <thread> #include <future> ... // Launch the thread. std::future<T_return>*  hThread    = new std::future<T_return>(std::async(std::launch::async, ThreadFnc, ...)); ... // Terminate the thread. if (hThread->wait_for(std::chrono::seconds(5))      == std::future_status::timeout) {    /* --- Do something, if thread has not terminated within 5 s. --- */  } else   delete hThread; 

where T_return is the return type of your thread procedure. This scenario uses an std::future / std::async combination instead of an std::thread.

Note that hThread is a pointer. When you call the delete operator on it, it will invoke the destructor of *hThread and block until the thread has terminated.

I have tested both versions with gcc 4.9.3 on Cygwin.

like image 26
ManuelAtWork Avatar answered Oct 04 '22 05:10

ManuelAtWork