我正在开发一个 C++ 项目,该项目使用 pthreads 进行多线程处理,但有时也需要这样做fork
。我已经阅读了代码中散布的警告,即以后永远不应该进行内存分配,但在找到这篇文章fork
之前我并不知道确切的原因。我总结了几点:
当主线程
fork
s时,其他线程可能正在调用某个库函数;fork
ing 不会复制其他线程,从而使调用永远卡住;malloc
使用全局变量,并使用锁来实现线程安全。因此,如果父进程的一个线程恰好在malloc
调用的中间,则fork
ed 子进程实际上有一个malloc
永远卡住且永远无法恢复的调用。同样的事情printf
,等等。
我意识到这与reentrancy有关,文章中没有提到这个术语。该声明似乎等同于:
f
如果在父进程的主线程中调用了一些非进入函数,子进程就不能调用f
。malloc
是不可重入的。
这是否正确,意味着所有可重入函数都可以在fork
ing 之后安全使用?还是我仍然错过了 pthread 和传统 UNIX 进程模型如何交互的一些讨厌的角落?
如果我是对的,还有另一个问题:malloc
已知是不可重入的,但是 C++new
呢?我在谷歌上搜索的相关结果并不多(主要是因为很难找到正确的“新”:),但至少有一个声明new
是可重入的。还有一个关于整个 C++ 标准库的相关问题没有令人满意的答案。
PS。对于感兴趣的,C++ 项目是fish shell。shell 肯定需要分叉,并且使用线程来提高响应能力。