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.
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.”
Join() Blocks the calling thread until the thread represented by this instance terminates, while continuing to perform standard COM and SendMessage pumping. Join(Int32)
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.
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.
There is no timeout for std::thread::join()
. However you can view std::thread::join()
as merely a convenience function. Using condition_variable
s 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With