手册页之间存在冲突,我不理解。
man 7 pthreads说:
POSIX.1-2001和POSIX.1-2008要求所有函数除以下功能:
和exit()不在线程安全异常列表中。
然而,男子3出口说:
exit()函数使用了一个不受保护的全局变量,因此它不是线程安全的。通过谷歌搜索,似乎exit()
实际上是线程不安全的。那么,我对手册页的理解有什么问题呢?为什么exit()
在man 7 pthreads
中没有被列为线程不安全?
为什么
exit()
在man 7 pthreads
中没有列为线程不安全?
这是文档作者的问题。但我可以说为什么它永远不应该被认为是线程安全的(从用户空间/c语言的角度来看)。它被明确列为:嗯,它很复杂。
您不能合法地调用exit
两次,这样就可以解决数据竞争问题。因为即使你这样做了,在调用了exit
或quick_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
变得不安全。