Reputation: 119572
pthread_detach
marks a thread so that when it terminates, its resources are automatically released without requiring the parent thread to call pthread_join
. How can it do this? From the perspective of Linux in particular, there are two resources in particular I am curious about:
wait
system call is not performed on the terminated thread, then the thread would become a zombie. I assume that the pthread library's solution to this problem does not involve SIGCHLD
, because (I think) it still works regardless of what action the program has specified to occur when SIGCHLD
is received.clone
system call. The caller must allocate memory to serve as the child thread's stack area before calling clone
. Elsewhere on Stack Overflow, it was recommended that the caller use mmap
to allocate the stack for the child. How can the stack be unmapped after the thread exits?It seems to me that pthread_detach
must somehow provide solutions to both of these problems, otherwise, a program that spawns and detaches many threads would eventually lose the ability to continue spawning new threads, even though the detached threads may have terminated already.
Upvotes: 0
Views: 254
Reputation: 76964
The pthreads library (on Linux, NPTL) provides a wrapper around lower-level primitives such as clone(2)
. When a thread is created with pthread_create
, the function passed to clone
is a wrapper function. That function allocates the stack and stores that information plus any other metadata into a structure, then calls the user-provided start function. When the user-provided start function returns, cleanup happens. Finally, an internal function called __exit_thread
is called to make a system call to exit the thread.
When such a thread is detached, it still returns from the user-provided start function and calls the cleanup code as before, except the stack and metadata is freed as part of this since there is nobody waiting for this thread to complete. This would normally be handled by pthread_join
.
If a thread is killed or exits without having run, then the cleanup is handled by the next pthread_create
call, which will call any cleanup handlers yet to be run.
The reason a SIGCHLD
is not sent to the parent nor is wait(2)
required is because the CLONE_THREAD
flag to clone(2)
is used. The manual page says the following about this flag:
A new thread created with CLONE_THREAD has the same parent process as the process that made the clone call (i.e., like CLONE_PARENT), so that calls to getppid(2) return the same value for all of the threads in a thread group. When a CLONE_THREAD thread terminates, the thread that created it is not sent a SIGCHLD (or other termination) signal; nor can the status of such a thread be obtained using wait(2). (The thread is said to be detached.)
As you noted, this is required for the expected POSIX semantics to occur.
Upvotes: 1