How is pthread_join implemented? How is pthread_join implemented? multithreading multithreading

How is pthread_join implemented?


pthread_join is probably internally implemented as a wait for a semaphore which is triggered when the thread exits, either when it calls pthread_exit or when its main function exits.

In any case, the source code for glibc is available, try google code search (I saw some informative stuff in there)


Yes that's the general idea. For gory details of a particular implementation take a look at glibc.


A thread typically has a little structure associated with it, the thread context. That structure can be stuffed with all the pieces of data which are needed to make the thread "work".

For instance, the root of a data structure needed to access the thread-specific keys of that thread, and to iterate over them to clean them up when it is being shut down.

There is typically a mutex-like lock in that structure, and perhaps more than one for different sections.

The thread context can have a little field in it where a terminating thread can place its exit status. (The void * returned by pthread_exit or by returning from the thread function.)

The thread context can also indicate the thread's state (not yet created, running, stopped).

There may be a synchronization primitive, such as a condition variable or semaphore, which the thread can kick, after preparing the termination status and indicating that it is terminating.

The pthread_join function can wait on that synchronization primitive. Once the wait finishes, the function can trigger a resource clean up for that thread, in addition to pulling out the status.

The thread continues to execute after signaling the join. To do that it must continue to have a context with a stack. After that point, the system has to work out the problem of cleanly stopping the thread in the background.

A user-space implementation of threading can defer that to the kernel. E.g. some signal can go off or whatever indicating that a thread has finished. At that point, user space knows that the thread cannot possibly be using its stack any more and can recycle it.

In the kernel, the scheduler can "eat" a thread. The thread can call some function in the scheduler which never returns after cleaning up most of its resources. It marks the thread as dead and switches context to another thread. The thread's stack will never be used again (since that function never returns) and can be reclaimed, as well as its task structure and any remaining things attached to it.