如何从任何线程安全地使用 exit()

How to use exit() safely from any thread

根据手册页 (2),exit 函数不是线程安全的:MT-Unsafe race:exit,这是因为此函数试图清理资源(将数据刷新到磁盘、关闭文件描述符等...) 通过调用使用 on_exitatexit 注册的回调。我希望我的程序能够做到这一点! (我的一个线程在整个程序的生命周期中保持 fd 打开,所以 _exit 不是我的选择,因为我希望所有数据都写入输出文件)

我的问题如下:如果我很小心并且不在我的线程之间共享任何敏感数据(如 fd),是否 "acceptable" 调用 exit多线程程序?请注意,如果发生不可恢复的错误,我只会调用 exit。然而,当程序试图退出时,我不能承受段错误。问题是,任何线程都可能发生不可恢复的错误...

我正在考虑使用 setjmp/longjmp 来终止我的线程 "nicely" 但这将非常复杂,并且需要在我的代码中进行许多更改。

如有任何建议,我们将不胜感激。谢谢 ! :)

编辑: 感谢@Ctx 启蒙,我想出了以下想法:

#define EXIT(status) do { pthread_mutex_lock(&exit_mutex); exit(status); } while(0)

当然 exit_mutex 必须是全局的(外部)。

联机帮助页指出

The exit() function uses a global variable that is not protected, so it is not thread-safe.

因此,如果您以任何方式小心,它也无济于事。

但记录的问题是竞争条件:MT-Unsafe race:exit

因此,如果您确定永远不会从两个线程同时调用 exit(),那么您应该是安全的!例如,您可以使用互斥锁来确保这一点。

这是不可能的:即使一开始线程之间没有共享数据,数据也必须在线程和它的清理函数之间共享。该函数应该 运行 只有在线程停止或到达安全点后。

现代跨平台 C++ 解决方案可以是:

#include <cstdlib>
#include <mutex>

std::mutex exit_mutex;

[[noreturn]] void exit_thread_safe(const int status)
{
    exit_mutex.lock();
    exit(status);
}

mutex 确保 exit 永远不会被 2 个(或更多)不同的线程调用。

但是,我仍然质疑甚至关心这个背后的原因。对 exit() 的多线程调用的可能性有多大?哪些坏事甚至可能实际发生?

编辑:
使用 std::quick_exit 可避免 clang 诊断警告。