我正在开发一个C ++项目,该项目使用pthread进行多线程处理,但偶尔还需要fork
。我已经阅读了分散在代码中的警告,内存分配应该在fork
之后永远不会完成,但在找到this article之前我并不确切知道原因。我总结了几点:
当主线程fork
s时,其他线程可能在某些库函数调用的中间; fork
不会复制其他线程,使得呼叫永远停留;
malloc
使用全局变量,并使用锁来实现线程安全。因此,如果父进程的一个线程恰好位于malloc
调用的中间,则fork
ed子进程实际上会永远停留malloc
个永远无法恢复的调用。 printf
等同样的事情
我意识到这与reentrancy有关,new
is reentrant这个词在文章中没有提及。声称似乎相当于:
如果您从父进程中的主线程调用某些非进入函数f
,则子进程无法调用f
。
malloc
不可重入。
这是否正确,这意味着在fork
之后可以安全地使用所有可重入函数?或者我是否仍然遗漏了pthreads和传统UNIX流程模型如何交互的一些令人讨厌的角落?
如果我是对的,还有另一个问题:malloc
已知是不可重入的,但是C ++的new
呢?我搜索了相关结果并不多(主要是由于难以找到正确的“新”:),但至少有一个声称是relevant question。关于整个C ++标准库还有一个fish shell没有令人满意的答案。
PS。对于感兴趣的人来说,C ++项目是{{3}}。 shell绝对需要分叉,并且使用线程来提高响应能力。
答案 0 :(得分:2)
正如@cnicutar所指出的那样,文章确实提到你可以在分叉后调用异步安全函数。根据{{3}},可重入函数总是没有异步(但不是相反),因此在分叉后调用是安全的。
这就是我的主要问题。我会在另一个帖子中提出另外的问题(没有双关语)。
更新:我问了其他问题this article。