There's a conflict between man pages which I don't understand.
man 7 pthreads says that:
POSIX.1-2001 and POSIX.1-2008 require that all functions specified in the standard shall be thread-safe, except for the following functions:
and exit() isn't in the thread-safety exception list.
However, man 3 exit says:
The exit() function uses a global variable that is not protected, so it is not thread-safe.
By googling it seems that exit()
is actually thread unsafe. So what's wrong with my understanding of man pages? Why is exit()
not listed as thread unsafe in man 7 pthreads
?
CodePudding user response:
Why is
exit()
not listed as thread unsafe inman 7 pthreads
?
That is a question for the documentation authors. But I can say why it should never be considered thread safe (from a userspace/c language perspective). It is explicitly listed as: well it's complicated.
You can't legally call exit
twice, so that takes care of the data race. Because even if you did it's already explictly undefined behavior to call exit
or quick_exit
anywhere in the application again after one of the two has been called.
Once you call exit
you've basically said to the runtime "Hey I need to tear down the house" the house being your application. The runtime then runs atexit
handlers per the standard.
Also worth noting is that atexit
handlers are not guaranteed thread safe but atexit
itself is, so if threads have registered their own atexit
handlers those will get called.
So what does all this mean:
exit
is not thread safe. But if you're tearing down the house does it really matter if the house was constructed to code anymore? Once you've called exit
and the atexit
handlers have finished then the kernel kills the threads, closes any handles, and reclaims everything. Worrying about closing the drapes when the bulldozer is coming through the wall is kind of pointless.
CodePudding user response:
The C standard disallows exit
from being called more than once. Section 7.22.4.4 regarding the exit
function paragraph 2 states:
The
exit
function causes normal program termination to occur. No functions registered by theat_quick_exit
function are called. If a program calls theexit
function more than once, or calls thequick_exit
function in addition to theexit
function, the behavior is undefined.
Additionally, the POSIX man page for exit
, i.e. man 3p exit
also states this:
If a function registered by a call to atexit() fails to return, the remaining registered functions shall not be called and the rest of the exit() processing shall not be completed. If exit() is called more than once, the behavior is undefined.
So the function is not thread safe by definition.
CodePudding user response:
Perhaps the answer is in https://man7.org/linux/man-pages/man3/pthread_exit.3.html
You call pthread_exit(). Not exit()
Eventually, when the last thread exits, exit is called for you.
CodePudding user response:
exit
is not thread-safe for these reasons:
it abruptly terminates all the threads. How can something which kills all the threads be "thread-safe"?
exit
must not be called more than once; that is undefined behavior. Therefore the basic thread-safety question "can this function be called from two threads at around the same time" is not answerable in the affirmative.exit
can execute arbitrary application code: theatexit
handlers. According to POSIX, calling theatexit
handlers is the first thing thatexit
does, and that means this happens while threads are running. These handlers can be badly written such that they lack thread safety, which means that their parent function,exit
, is rendered unsafe.