2

我正在开发一个 C++ 项目,该项目使用 pthreads 进行多线程处理,但有时也需要这样做fork。我已经阅读了代码中散布的警告,即以后永远不应该进行内存分配,但在找到这篇文章fork之前我并不知道确切的原因。我总结了几点:

  1. 当主线程forks时,其他线程可能正在调用某个库函数;forking 不会复制其他线程,从而使调用永远卡住;

  2. malloc使用全局变量,并使用锁来实现线程安全。因此,如果父进程的一个线程恰好在malloc调用的中间,则forked 子进程实际上有一个malloc永远卡住且永远无法恢复的调用。同样的事情printf,等等。

我意识到这与reentrancy有关,文章中没有提到这个术语。该声明似乎等同于:

  1. f 如果在父进程的主线程中调用了一些非进入函数,子进程就不能调用f

  2. malloc是不可重入的。

这是否正确,意味着所有可重入函数都可以在forking 之后安全使用?还是我仍然错过了 pthread 和传统 UNIX 进程模型如何交互的一些讨厌的角落?

如果我是对的,还有另一个问题:malloc已知是不可重入的,但是 C++new呢?我在谷歌上搜索的相关结果并不多(主要是因为很难找到正确的“新”:),但至少有一个声明new 可重入的。还有一个关于整个 C++ 标准库的相关问题没有令人满意的答案。

PS。对于感兴趣的,C++ 项目是fish shell。shell 肯定需要分叉,并且使用线程来提高响应能力。

4

1 回答 1

2

正如@cnicutar 所指出的,文章确实提到您可以在分叉后调用异步安全函数。根据这篇文章,可重入函数始终是异步的(但不是相反),因此在分叉后调用是安全的。

我的主要问题到此结束。我会在另一个线程中问额外的问题(没有双关语)。

更新:我在这里问了额外的问题。

于 2012-12-30T11:59:05.177 回答