Home > OS >  Man pages conflict on thread-safe
Man pages conflict on thread-safe

Time:09-29

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 in man 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 the at_quick_exit function are called. If a program calls the exit function more than once, or calls the quick_exit function in addition to the exit 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: the atexit handlers. According to POSIX, calling the atexit handlers is the first thing that exit 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.

  • Related