[英]What does the POSIX standard say about thread stacks in atexit() handlers? What's the OS practice?
当我们的UNIX / C程序需要紧急出口时,我们使用exit(3)函数并安装atexit(3)处理程序以进行紧急清理。 这种方法工作正常,直到我们的应用程序被线程化,此时atexit()处理程序停止工作可预测。
我们通过试验了解到一个错误,即线程可能已经死在atexit()处理程序中,并且它们的堆栈已经解除分配。
我没有在标准链接线程消失中找到引用atexit():从main()返回后线程停止存在,但它是在调用atexit()之前还是之后? Linux,FreeBSD和Mac上的实际操作是什么?
在多线程程序中是否有一个很好的紧急清理模式?
Posix标准
Posix似乎没有定义是否在线程被exit
终止之前或之后调用atexit
处理程序。
进程有“正常”终止的方式有两种(或三种)方式。
所有线程终止。 当最后一个线程退出时,无论是通过返回还是调用pthread_exit
,都会运行atexit
处理程序。 在这种情况下,没有其他线程。 (这是平台相关的。如果主线程除了exit
而其他线程没有终止,某些平台可能会终止其他线程)。
一个线程调用exit
。 在这种情况下,将运行atexit
处理程序并终止所有线程。 Posix没有指定以什么顺序。
main
回报。 这或多或少等于调用exit()
作为main
的最后一行,因此可以如上所述进行处理。
OS实践
在Linux中,文档https://linux.die.net/man/2/exit表示线程由_exit
调用exit_group
终止,而_exit
在atexit
处理程序之后调用。 因此,在Linux上调用exit
任何atexit
处理程序都会在线程终止之前运行。 请注意,它们在线程调用exit
上运行,而不是在调用atexit
的线程上运行。
在Windows上,如果您关心,行为是相同的。
紧急清理模式。
最好的模式是: 永远不要处于需要紧急清理的状态。
kill -9
或停电。 abort
恢复,因此您可以使用abort
来进行紧急出口。 如果你不能这样做,或者如果你想要做“很好的”清理,那么atexit
处理程序应该没问题, 只要你首先优雅地停止进程中的所有线程以防止在进行清理时进入不一致状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.