c-线程安全上的手册页冲突



手册页之间存在冲突,我不理解。

man 7 pthreads说:

POSIX.1-2001和POSIX.1-2008要求所有函数除以下功能:

和exit()不在线程安全异常列表中。

然而,男子3出口说:

exit()函数使用了一个不受保护的全局变量,因此它不是线程安全的。

通过谷歌搜索,似乎exit()实际上是线程不安全的。那么,我对手册页的理解有什么问题呢?为什么exit()man 7 pthreads中没有被列为线程不安全?

为什么exit()man 7 pthreads中没有列为线程不安全?

这是文档作者的问题。但我可以说为什么它永远不应该被认为是线程安全的(从用户空间/c语言的角度来看)。它被明确列为:嗯,它很复杂。

您不能合法地调用exit两次,这样就可以解决数据竞争问题。因为即使你这样做了,在调用了exitquick_exit中的一个之后,在应用程序中的任何地方再次调用它们都是明确未定义的行为。

一旦你调用CCD_ 9,你基本上已经对运行时说:;嘿,我需要把房子拆掉;房子是你的申请。运行时然后根据标准运行atexit处理程序。

同样值得注意的是,atexit处理程序不能保证线程安全,但atexit本身是线程安全的,因此,如果线程已经注册了自己的atexit处理程序,就会调用这些处理程序。

那么这一切意味着什么:

exit不是线程安全的。但是,如果你要拆除房子,房子是否按照代码建造真的重要吗?一旦调用了exit并且atexit处理程序完成,内核就会终止线程,关闭所有处理程序,并回收所有内容。当推土机穿过墙壁时,担心窗帘会关上是毫无意义的。

C标准不允许exit被多次调用。关于exit功能的第7.22.4.4节第2段规定:

exit函数会导致正常程序终止。不调用由CCD_ 20函数注册的函数。如果程序多次调用exit函数,或者除了调用exit函数外还调用quick_exit函数,则行为未定义

此外,exit(即man 3p exit)的POSIX手册页也指出:

如果调用atexit()注册的函数未能返回,则不应调用剩余的已注册函数exit()则不应完成处理如果exit()被调用多次,则行为是未定义的

因此,根据定义,该函数不是线程安全的。

也许答案在https://man7.org/linux/man-pages/man3/pthread_exit.3.html
您调用pthread_exit()。Not exit()
最终,当最后一个线程退出时,会为您调用exit。

exit不是线程安全的,原因如下:

  • 它会突然终止所有线程。杀死所有线程的东西怎么可能是"线程"呢;线程安全";?

  • exit的调用次数不得超过一次;这是未定义的行为。因此,基本的螺纹安全问题";这个函数可以同时从两个线程调用吗;不能肯定地回答。

  • exit可以执行任意的应用程序代码:atexit处理程序。根据POSIX,调用atexit处理程序是exit所做的第一件事,这意味着在线程运行时会发生这种情况。这些处理程序可能编写得很糟糕,从而缺乏线程安全性,这意味着它们的父函数exit变得不安全。