Detached vs. Joinable POSIX threads
Asked Answered
B

2

67

I've been using the pthread library for creating & joining threads in C.

  1. When should I create a thread as detached, right from the outset? Does it offer any performance advantage vs. a joinable thread?

  2. Is it legal to not do a pthread_join() on a joinable (by default) thread? Or should such a thread always use the detach() function before pthread_exit()ing?

Bovine answered 21/9, 2010 at 2:22 Comment(0)
C
87
  1. Create a detached thread when you know you won't want to wait for it with pthread_join(). The only performance benefit is that when a detached thread terminates, its resources can be released immediately instead of having to wait for the thread to be joined before the resources can be released.

  2. It is 'legal' not to join a joinable thread; but it is not usually advisable because (as previously noted) the resources won't be released until the thread is joined, so they'll remain tied up indefinitely (until the program exits) if you don't join it.

Carvel answered 21/9, 2010 at 3:4 Comment(7)
doubt: in case of detached threads, what if the main thread finishes executing before the detached thread is finished? I think this would terminate the process killing all the threads. So In what scenarios are detached threads used because I should be sure that detached thread has finished execution?Sectary
@Ajax: Empirically, if the main thread finishes, the program exits and the threads are … terminated. That, at least, seems to be the behaviour on Mac OS X (10.10.1 Yosemite). I can find nothing in the POSIX documentation that indicates other threads continue if exit() or _exit() or _Exit() is called. If the main thread does pthread_exit(), then the other threads do get a chance to complete.Carvel
On a different note: Detachable threads are good for when you already have some other polling mechanism in place; you can use that same polling mechanism to check result state, and so know whether or not the thread completed. It's a case of, "Is it ready? If so, use it."Poor
Can I call pthread_detach before it exits in order to avoid memory leaks if I forget to call pthread_join?Squarrose
@DareDevil: Yes, but…. You should be detaching the thread because you don't need to know the thread's return status and you don't need to know that it has finished, rather than because you might forget to join it. And once you've detached, you must not try to join the thread.Carvel
So, terminating and releasing the resources are two different things not happening at the same time? Also, what resources are released when a thread is joined (or terminated when detached) ?Esoterica
Yes — "terminating and releasing the resources are two different things not happening at the same time". When the thread terminates, it ceases execution and cannot be reactivated. A non-detached thread continues to occupy a slot in the list of all threads. The resources are primarily things like the thread control information — I would expect the stack to be released when the thread terminates, but the information about the exit value and thread ID must be maintained if the thread can be joined, but not if it is detached. This is usually not a huge amount of data, but it isn't zero either.Carvel
S
6

When should I create a thread as detached, right from the outset?

Whenever the application doesn't care when that thread completes and doesn't care about its return value of a thread, either (a thread may communicate a value back to other thread/application via pthread_exit).

For example, in a client-server application model, a server may create a new thread to process each request. But the server itself doesn't care about thread's return value of the thread. In that case, it makes sense to created detached threads.

The only thing the server needs to ensure is that the currently processed requests are completed. Which it can do so, just by exiting the main thread without exiting the whole program/application. When the last thread in the process exits, the application/program will naturally exit.

The pseudocode might look like:

/* A server application */

void process(void *arg)
{
    /* Detach self. */
    pthread_detach(pthread_self());
    
    /* process a client request. */
    
    pthread_exit(NULL);
}

int main(void)
{

    while (not_done) {
        pthread_t t_id;
        errno = pthread_create(&t_id, NULL, process, NULL);
        if (errno) perror("pthread_create:");
    }

    /* There may be pending requests at this point. */
    
    /* Just exit the main thread - not the whole program - so that remaining
       requests that may still be processed can continue. */
    pthread_exit(NULL);
}

Another example could be a daemon or logger thread that logs some information at regular intervals for as long as the application runs.

Does it offer any performance advantage vs. a joinable thread?

Performance-wise, there's no difference between joinable threads vs detached threads. The only difference is that with detached threads, its resources (such as thread stack and any associated heap memory, and so on - exactly what constitutes those "resources" are implementation-specific).

Is it legal to not do a pthread_join() on a joinable (by default) thread?

Yes, it's legal to not join with a thread. pthread_join is a just convenience function that's by no means needs to be used unless you need. But note that the threads created are joinable threads by default.

An example when you might want to join is when threads do a "piece" of work that's split between them. In that case, you'd want to check all threads complete before proceeding. Task farm parallelism is a good example.

Or should such a thread always use the detach() function before pthread_exit()ing?

Not necessary. But you'd often want to decide whether you want a joinable or detached thread at the time of creation.


Note that while a detachable thread can be created in by setting the attribute PTHREAD_CREATE_DETACHED with a call to pthread_attr_setdetachstate, a thread decide can decide to detach itself at any point in time e.g. with pthread_detach(pthread_self()). Also, a thread that has the thread id (pthread_t) of another thread can detach with pthread_detach(thread_id);.

Scavenger answered 18/7, 2020 at 19:58 Comment(2)
What's the difference between "exiting the main thread" and "exiting the whole program/application"?Foretaste
@YdAhhrk Calling pthread_exit from main thread exits just that thread and the process will continue to run if there are other threads running. That's what I mean by "exiting the main thread". OTOH, calling exit from any thread exits the whole process/application, for example.Scavenger

© 2022 - 2024 — McMap. All rights reserved.