繁体   English   中英

POSIX标准对atexit()处理程序中的线程堆栈有何看法? 什么是操作系统的做法?

[英]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终止,而_exitatexit处理程序之后调用。 因此,在Linux上调用exit任何atexit处理程序都会在线程终止之前运行。 请注意,它们在线程调用exit上运行,而不是在调用atexit的线程上运行。

在Windows上,如果您关心,行为是相同的。

紧急清理模式。

最好的模式是: 永远不要处于需要紧急清理的状态。

  • 无法保证您的清理能够运行,因为您可能会遇到kill -9或停电。
  • 因此,您需要能够在该场景中恢复。
  • 如果您可以从中恢复,您也可以从abort恢复,因此您可以使用abort来进行紧急出口。

如果你不能这样做,或者如果你想要做“很好的”清理,那么atexit处理程序应该没问题, 只要你首先优雅地停止进程中的所有线程以防止在进行清理时进入不一致状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM