Multithreading 混合线程、fork和互斥体,我应该注意什么?
如果我使用Multithreading 混合线程、fork和互斥体,我应该注意什么?,multithreading,fork,mutex,Multithreading,Fork,Mutex,如果我使用fork一个进程,其中一个线程持有互斥锁,那么如果我在子进程中立即执行exec,我是否相对安全?在Iexec之前,在孩子身上做什么事情是安全的 如果执行fork的线程在调用exec之前继续释放互斥锁,这会导致问题吗?如果我试图在父进程在fork之前拥有的子进程中获取互斥锁(可能拥有也可能不拥有),会发生什么情况 不同平台上的答案是否不同?我主要关注Unix变体,尤其是Linux。但我对NT很好奇。当然,据我所知,NT没有fork有关多线程环境中fork相关问题的讨论,请参见,尤其是基本
fork
一个进程,其中一个线程持有互斥锁,那么如果我在子进程中立即执行exec
,我是否相对安全?在Iexec
之前,在孩子身上做什么事情是安全的
如果执行fork
的线程在调用exec
之前继续释放互斥锁,这会导致问题吗?如果我试图在父进程在fork
之前拥有的子进程中获取互斥锁(可能拥有也可能不拥有),会发生什么情况
不同平台上的答案是否不同?我主要关注Unix变体,尤其是Linux。但我对NT很好奇。当然,据我所知,NT没有fork
有关多线程环境中fork
相关问题的讨论,请参见,尤其是基本原理部分。它还提供了一个提示,说明在子级和父级中,在fork
之前和之后什么应该是有效的
更新:基本原理部分不规范,结果与标准的其他部分冲突。有关更多详细信息,请参见Dave Butenhof
在fork
之后立即exec
对于多线程程序的任何状态(即,持有任何互斥锁的任何线程)都是安全的。至于fork
和exec
之间可能发生的事情,情况很复杂:
最重要的是在子进程中只复制一个线程(称为fork
)。因此,在fork
时刻由另一个线程持有的任何互斥锁都将被永久锁定。也就是说(假设非进程共享互斥体),它在子进程中的副本被永久锁定,因为没有线程来解锁它
如果可能,在fork
之后释放互斥锁是安全的,也就是说,如果fork
ing线程首先拥有互斥锁。这就是pthread\u atfork
处理程序通常的工作方式:在fork
之前锁定互斥体,在子级解锁,在父级解锁
在获取fork之前进程拥有的互斥锁时(请记住,我们讨论的是子级地址空间中的一个副本):如果它属于fork
ing线程,则它是递归锁定(适用于PTHREAD\u mutex\u recursive
);如果它被另一个线程拥有,它将永远被锁定,无法重新获取
通过注册适当的pthread\u atfork
处理程序,第三方库可以保证在fork
和exec
之间安全使用。(我希望它主要来自编程语言运行时,而不是通用库)
经过进一步的研究,我建议不要以任何方式依赖
pthread_atfork
,而只在fork
和exec
之间进行异步信号安全调用(放弃fork
/exec
forposix_spawn
会更好)
问题是,fork
本身可以在信号处理程序中调用。它排除了对pthread_atfork
的任何非常规使用,即使其基本原理明确提到在子进程中解锁互斥锁和重新创建线程(!)
我认为不同解释的“灰色地带”仍然存在:
fork
的程序中的pthread\u atfork
处理程序李>
fork
调用周围