Non-blocking pthread_join

Solution 1:

If you are running your application on Linux, you may be interested to know that:

int pthread_tryjoin_np(pthread_t thread, void **retval);

int pthread_timedjoin_np(pthread_t thread, void **retval,
                                const struct timespec *abstime);

Be careful, as the suffix suggests it, "np" means "non-portable". They are not POSIX standard, gnu extensions, useful though.

link to man page

Solution 2:

The 'pthread_join' mechanism is a convenience to be used if it happens to do exactly what you want. It doesn't do anything you couldn't do yourself, and where it's not exactly what you want, code exactly what you want.

There is no real reason you should actually care whether a thread has terminated or not. What you care about is whether the work the thread was doing is completed. To tell that, have the thread do something to indicate that it is working. How you do that depends on what is ideal for your specific problem, which depends heavily on what the threads are doing.

Start by changing your thinking. It's not a thread that gets stuck, it's what the thread was doing that gets stuck.

Solution 3:

If you're developing for QNX, you can use pthread_timedjoin() function.

Otherwise, you can create a separate thread that will perform pthread_join() and alert the parent thread, by signalling a semaphore for example, that the child thread completes. This separate thread can return what is gets from pthread_join() to let the parent thread determine not only when the child completes but also what value it returns.

Solution 4:

As others have pointed out there is not a non-blocking pthread_join available in the standard pthread libraries.

However, given your stated problem (trying to guarantee that all of your threads have exited on program shutdown) such a function is not needed. You can simply do this:

int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
   int return = pthread_cancel(threads[i]);
   if(return != ESRCH)
      killed_threads++;
}
if(killed_threads)
    printf("%d threads did not shutdown properly\n", killed_threads)
else
    printf("All threads exited successfully");

There is nothing wrong with calling pthread_cancel on all of your threads (terminated or not) so calling that for all of your threads will not block and will guarantee thread exit (clean or not).

That should qualify as a 'simple' workaround.