4
votes

From https://computing.llnl.gov/tutorials/pthreads/:

A joining thread can match one pthread_join() call. It is a logical error to attempt multiple joins on the same thread.

Also from "man pthread_join":

If multiple threads simultaneously try to join with the same thread, the results are undefined.

However, from programmer's point of view, it makes a perfect sense that multiple threads may want to wait for a single thread to complete (similar to barriers).

For example, we may have thread1, thread2 running independently, and we may want both threads to wait until thread3 is completed.

Is there any technical reason behind this restriction?

2
Once pthread_join() returns, the last resources associated with the exited thread are released. No other pthread_join() can touch that thread, because nothing of it remains. It has to be that way, how else would the pthread-library know when to release those resources? If multiple threads could join with one pthread, you'd have a permanent resource leak for every exited thread.EOF
So, the resource (return value) of a terminated thread is kept in memory until FIRST thread actually joins and claims it? Just like first come first served?SHH
Not quite. It's "first come, first served, and if anyone else comes afterwards there'll be hell to pay".EOF
I can say what the reason is but their might be unpleasant work arounds, like pthread_detach and maybe finding some destructor or locks that get released to select for.jgmjgm

2 Answers

7
votes

I believe the technical reason is that pthread_join is a POSIX standard which, for multithreading, tries to specify only necessary primitives for implementers. Any richer semantics would introduce a costlier implementation and perhaps a more difficult API.

Indeed, POSIX already considers this function to be a convenience, rather than a primitive, in support of a very, very common use case: one thread waits for the termination of one other.

The first paragraph of the POSIX.1-2008 pthread_join RATIONALE is a bit lengthy, but makes many germane observations:

The pthread_join() function is a convenience that has proven useful in multi-threaded applications. It is true that a programmer could simulate this function if it were not provided by passing extra state as part of the argument to the start_routine(). The terminating thread would set a flag to indicate termination and broadcast a condition that is part of that state; a joining thread would wait on that condition variable. While such a technique would allow a thread to wait on more complex conditions (for example, waiting for multiple threads to terminate), waiting on individual thread termination is considered widely useful. Also, including the pthread_join() function in no way precludes a programmer from coding such complex waits. Thus, while not a primitive, including pthread_join() in this volume of POSIX.1-2008 was considered valuable.

0
votes

There is a huge difference between Posix pthreads and Windows Kernel Objects (which I blatantly assume you are familiar with). I find it with unpleasant limitations, and you mentioned just one. There is no real technical reason for this beside current implementation details (yes, thread state is not kept in memory after join, but why?). The other very unpleasant limitation is lack of possiblity to join multiple threads in one call - which probits multiplexing on threads.

Still, millions of pthread-based programms are ran every day, so those limitations are not a show stopper. But indeed, certain tasks would be easier to perform without those.