在多线程(带有pthreads)进程中的fork()之后,所有可重入函数都可以安全使用吗? [英] Are all reentrant functions safe to use after fork()ing in a multithreaded(with pthreads) process?
问题描述
我正在一个C ++项目中,该项目使用pthreads进行多线程处理,但还需要不时地fork
.我已经阅读了分散在代码中的警告,警告说在fork
之后绝对不应该进行内存分配,但是我不完全知道为什么找到这篇文章.我总结了要点:
I'm working on a C++ project which employs pthreads for multithreading, but also needs to fork
now and then. I've read warnings scattered in the code that memory allocation should never be done after fork
, but I didn't know exactly why before I found this article. I've summarized the points:
-
当主线程
fork
时,其他线程可能在某些库函数调用的中间;fork
ing不会复制其他线程,从而使调用永久停止;
When the main thread
fork
s, the other threads may be in the middle of some library function call;fork
ing doesn't copy the other threads, making the calls stuck forever;
malloc
使用全局变量,并使用锁来实现线程安全.因此,如果父进程的线程之一恰好在malloc
调用的中间,则fork
ed子进程实际上有效地永远阻塞了malloc
调用,该调用永远无法恢复. printf
等也一样
malloc
uses global variable, and employs locks to achieve thread safety. So if one of threads of the parent process happen to be in the middle in a malloc
call, the fork
ed child process has effectively a malloc
call stuck forever that can never recover. Same thing for printf
, etc.
我意识到这与 reentrancy 有关.在这篇文章中没有提到.该声明似乎等同于:
I realized that this has something to do with reentrancy, a term that is not mentioned in the article. It seems that the claim is equivalent to:
-
如果您在父进程的主线程之外调用了一些非进入函数
f
,则子进程无法调用f
.
If you called some non-entrant function
f
off the main thread in the parent process, the child process can not callf
.
malloc
是不可重入的.
这是正确的,这意味着在fork
之后可以安全地使用所有可重入函数吗?还是我仍然缺少pthread和传统UNIX流程模型如何交互的烦人之处?
Is this correct, meaning that all reentrant functions may be safely used after fork
ing? Or am I still missing some nasty corners of how pthreads and traditional UNIX process model interact?
如果我是对的,还有另一个问题:malloc
被认为是不可重入的,但是C ++的new
呢?我为此搜索了很多相关结果(主要是由于很难找到正确的"new" :),但是至少有一种说法是有关整个C ++标准库的相关问题,没有令人满意的答案.
If I am right, there is another question: malloc
is known to be non-reentrant, but what about C++'s new
? I googled for that with not many relevant results (mostly due to the difficulty to hit the correct "new" :), but there is at least one claim that new
is reentrant. There is also a relevant question concerning the whole C++ standard library with no satisfying answer.
PS.对于感兴趣的人,C ++项目是鱼壳.外壳肯定需要分叉,并且使用线程来提高响应速度.
PS. For the interested, the C++ project is the fish shell. Forking is definitely needed for shells, and threads are employed to improve responsiveness.
推荐答案
正如@cnicutar指出的那样,该文章确实提到您可以在派生后调用异步安全函数.根据本文,可重入函数始终是异步(但并非相反),因此在分叉后可以安全地调用.
As pointed out by @cnicutar, the article did mention that you can call async-safe functions after forking. And according to this article, reentrant functions are always async-free (but not the opposite), thus safe to call after forking.
这就是我的主要问题.我会在另一个线程中问这个额外的问题(无双关语).
That concludes my main question. I'll ask the additional question in another thread (no pun intended).
已更新:我在此处提出了其他问题.
Updated: I asked the additional question here.
这篇关于在多线程(带有pthreads)进程中的fork()之后,所有可重入函数都可以安全使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!