Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling pthread_detach for an already exited thread?

Tags:

c

pthreads

#include <pthread.h>
#include <unistd.h>

static void *tfunc(void *data)
{
    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t t;

    pthread_create(&t, NULL, tfunc, NULL);
    sleep(1);
    pthread_detach(t);

    return 0;
}

See the MWE. It works fine, but I am unsure if this is actually defined behavior. The man page of pthread_detach says nothing about calling it on exited threads.

Yes I know about creating threads with the detached attribute, but I am specifically curious about this situation. pthread_join has a mention on this case and I assume pthread_detach works just as fine, but I haven't found any official statement.

like image 328
flowit Avatar asked Oct 30 '25 03:10

flowit


1 Answers

This code is perfectly legal, and does not invoke undefined behavior:

#include <pthread.h>
#include <unistd.h>

static void *tfunc(void *data)
{
    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t t;

    pthread_create(&t, NULL, tfunc, NULL);
    sleep(1);
    pthread_detach(t);

    return 0;
}

It's not really clearly stated, but the POSIX documentation for pthread_detach() is worded in such a way that it must be defined and correct to call pthread_detach() on a terminated thread:

The pthread_detach() function shall indicate to the implementation that storage for the thread thread can be reclaimed when that thread terminates. If thread has not terminated, pthread_detach() shall not cause it to terminate.

The behavior is undefined if the value specified by the thread argument to pthread_detach() does not refer to a joinable thread.

First, note the statement "If thread has not terminated". That implies that it must be safe to call pthread_detach() when the thread has terminated.

Second, note "The behavior is undefined if ... does not refer to a joinable thread." In your posted code, the thread you created is clearly joinable - you didn't create it with a detached attribute, so you could call pthread_join() to retrieve its returned value. So it's not undefined behavior.

Remember, there's no guaranteed way to ensure from thread A that thread B is still running when either pthread_join() or pthread_detach() is called. So either call has to be safe to call (once!) from any thread on any other thread.

Also, from the Rationale section of the POSIX documentation:

RATIONALE

The pthread_join() or pthread_detach() functions should eventually be called for every thread that is created so that storage associated with the thread may be reclaimed.

It has been suggested that a "detach" function is not necessary; the detachstate thread creation attribute is sufficient, since a thread need never be dynamically detached. However, need arises in at least two cases:

  1. In a cancellation handler for a pthread_join() it is nearly essential to have a pthread_detach() function in order to detach the thread on which pthread_join() was waiting. Without it, it would be necessary to have the handler do another pthread_join() to attempt to detach the thread, which would both delay the cancellation processing for an unbounded period and introduce a new call to pthread_join(), which might itself need a cancellation handler. A dynamic detach is nearly essential in this case.

  2. In order to detach the "initial thread" (as may be desirable in processes that set up server threads).

Again, while not clearly stated, note the implied equivalence between pthread_join() and pthread_detach().

like image 153
Andrew Henle Avatar answered Oct 31 '25 22:10

Andrew Henle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!