是否可以在现代 C++ 中使用 fork?

Is it possible to use fork in modern C++?

传统的 C++ 非常简单,只有一个旨在创建线程的库(如 pthread)会产生其他线程。

现代 C++ 更接近 Java,许多函数都是基于线程的,线程池准备好 运行 异步作业等。更有可能是一些库,包括标准库,使用线程异步计算某些函数,或者设置基础结构来执行此操作,即使它没有被使用。

在这种情况下,使用像 fork 这样具有全局影响的函数是否安全?

与 C++ 中几乎所有其他问题一样,这个问题的答案是 "it depends"。

如果我们假设程序中还有其他线程,并且这些线程正在相互同步,那么调用 fork 是危险的。这是因为,fork不会等待所有线程都成为一个同步点(即互斥量释放)来fork进程。在分叉的进程中,只有调用 fork 的线程会出现,其他线程将被终止,可能在关键部分的中间。这意味着任何与其他线程共享的内存,不是 std::atomic<int> 或类似的,都是未定义的状态。

如果您的分叉进程从此内存中读取,或者确实期望其他线程是 运行,则它可能无法可靠地工作。但是,fork 的大多数用途实际上 没有程序状态 的先决条件。这是因为最常见的做法是立即调用 execv 或类似的方法来生成子进程。在这种情况下,您的整个进程有点 "replaced" 被某个新进程占用,并且旧进程的所有内存都被丢弃。

tl;dr - 在多线程程序中调用 fork 可能不安全。有时是安全的;就像还没有产生任何线程,或者立即调用 evecv 一样。如果您将 fork 用于其他用途,请考虑改用线程。

请参阅 fork man page and this helpful blog post 了解详情。

为了补充 peteigel 的回答,我的建议是 - 如果您想分叉,请尽早进行,在除主线程之外的任何其他线程启动之前进行。

一般来说,任何你能用 C 做的事,你也能用 C++ 做,因为 C++,尤其是 Linux 上的 clang 或 gcc 扩展,非常接近 C 的完美超集。当然,当标准 C++ 中有好的可移植 APIs 时,使用它们。典型示例更喜欢 std::thread 而不是 pthreads C API.

一个警告是 pthread_cancel,由于异常,必须在 C++ 上避免。参见例如pthread cancel harmful on C++.

这是另一个 link 来解释问题: pthread_cancel while in destructor

一般来说,C++ 清理处理通常比 C 更容易、更优雅,因为 RAII 是 C++ 文化的重要组成部分,而 C 没有析构函数。