Lets say I spawn 4 threads, running these functions
int func1() {sleep(2); return 1};
int func2() {sleep(4); return 0};
int func3() {sleep(6); return 2};
int func4() {sleep(8); return 3};
I want to wait for them to complete, but with a deadline of 7 seconds.
Additionally, if one of them finishes before the deadline and returns a 0, then I don't need to wait for any of the other ones to complete.
So for this example, I'd like to stop waiting for all other threads as soon as func2()
finishes because it returns a 0.
Lets say I spawn 4 threads, running these functions
int func1() {sleep(2); return 1};
int func2() {sleep(4); return 0};
int func3() {sleep(6); return 2};
int func4() {sleep(8); return 3};
I want to wait for them to complete, but with a deadline of 7 seconds.
Additionally, if one of them finishes before the deadline and returns a 0, then I don't need to wait for any of the other ones to complete.
So for this example, I'd like to stop waiting for all other threads as soon as func2()
finishes because it returns a 0.
2 Answers
Reset to default 4I want to wait for them to complete but with a deadline 7 seconds. Additionally, if one of them finishes before the deadline and return a 0, then I don't need to wait for any of the other ones to complete.
Pthreads does not define any way to do that as written. pthread_join()
is the only mechanism it defines for one thread to wait for another to terminate, or to retrieve a thread's return value. That does not accommodate one thread waiting for more than one other thread at a time, nor does it provide for a timeout.
If you were willing to engage non-standard extensions then possibly pthread_timedjoin_np() and / or pthread_tryjoin_np() could get you further (if you have them). The former still provides only for waiting on one thread, but it allows you to timeout if the target thread does not terminate by a specified time. The latter also provides waiting only on one thread, but it fails immediately if that thread has not already terminated. For your particular case, then, you could busy-wait for the threads of interest, calling pthread_tryjoin_np()
for each one in turn until the allotted time expires or you are satisfied with one of the threads' return values.
If you end up with any threads whose termination you no longer want to await, but you want the overall program to continue, then you should probably pthread_detach()
those threads.
Frame challenge:
You said you want to use the threads' return values, but perhaps it would be sufficient to use results reported out of the threads by other means. This is much more flexible. For example,
you could let the threads each store their result in shared memory, and use a condition variable to provide for your main thread to wait, with timeout, for any of those results to be written (see
pthread_cond_timedwait()
).OR
you could set up a pipe or socket by which the threads report their results, or maybe one per thread, and let the main thread use
select()
/poll()
/ etc to wait, with timeout, for results.
You might want to combine this with detaching the threads, which you could do as soon as you start them if you rely on this kind of approach (or even start them already detached).
The caveat here is that for something like this to work, you need the thread functions to cooperate with you. In practice, however, that is rarely an issue because you're ordinarily in control of the work your threads are performing.
You can use a shared flag with pthread_mutex
and pthread_cond_timedwait
to wait up to 7 seconds but exit early if a thread returns 0
. Each thread runs its function, and if it returns 0
, it signals a condition variable. The main thread waits on this condition, and if signaled, it cancels the remaining threads using pthread_cancel
. If no thread returns 0
, it simply times out after 7 seconds. This ensures you stop waiting as soon as needed while avoiding unnecessary delays.
void *()(void *)
-- that is, it accepts one argument of typevoid *
and returnsvoid *
. – John Bollinger Commented Feb 17 at 16:35WaitForMultipleObjects
waiting for the thread handles themselves. Optionally with a specified deadline parameter. Windows also got SleepEx which can be used to wake up sleeping threads and have them terminate gracefully. – Lundin Commented Feb 18 at 14:52