Omn*_*ous 7 multithreading mutex fork
如果我fork是一个线程持有互斥锁的进程,如果我立刻exec在孩子身上,我相对安全吗?在我之前,孩子们可以做些什么事情exec?
如果执行的线程fork然后子进程在调用之前继续释放互斥锁exec会导致问题吗?如果我尝试获取父进程之前拥有的子进程fork(并且可能或可能仍然拥有)的子进程,会发生什么?
不同平台上的答案有何不同?我主要关注的是Unix变体,特别是Linux.但我对NT感到好奇.当然,虽然NT(据我所知)没有fork.
有关多线程环境中与之相关的问题的讨论,请参阅pthread_atfork,尤其是RATIONALE部分fork.它还提示了在fork孩子和父母之前和之后应该有效的内容.
更新:理论部分是非规范性的,结果证明与标准的其他部分相冲突.有关详细信息,请参阅Dave Butenhof的此缺陷报告.
立即exec之后fork应该是对多线程程序的任何国家安全(即持有的所有互斥锁的线程).由于之间可能存在的东西fork和exec,情况是复杂的:
最重要的是fork在子进程中只复制一个线程(被调用的线程).因此,当前另一个线程持有的任何互斥fork锁都会永久锁定.这是(假设非进程共享的互斥锁)其子进程中的副本永远被锁定,因为没有线程可以解锁它.
fork在可能的情况下释放互斥锁是安全的,也就是说,如果forking线程首先拥有互斥锁.这就是pthread_atfork处理程序通常的工作方式:锁定互斥锁之前fork,解锁子级并解锁父级.
获取一个在fork之前拥有进程的互斥锁(记住,我们在子地址空间中讨论一个副本):如果它由一个ing线程拥有fork,那么它是递归锁定(适用于PTHREAD_MUTEX_RECURSIVE); 如果它由另一个线程拥有,它将永远保持锁定状态,无法重新获取.
通过注册适当的pthread_atfork处理程序,第三方库可以保证在fork和之间安全使用exec.(我希望它主要来自编程语言运行时,而不是通用库).
一些研究之后,我会建议避免依赖任何方式上pthread_atfork,无所事事,但异步信号安全的调用之间fork和exec(放弃fork/ exec的posix_spawn会更好).
问题是,fork本身可以在信号处理程序中调用.它排除了任何重要的使用pthread_atfork,即使它的RATIONALE明确提到解锁互斥锁并在子进程中重新创建线程(!).
我认为不同可能解释的"灰色地带"仍然存在:
pthread_atfork其中的程序处理程序称为永远不会调用fork一个信号处理程序.fork调用周围发生的非pthread-atfork操作.但很清楚哪种读数将用于便携式应用.
| 归档时间: | 
 | 
| 查看次数: | 5496 次 | 
| 最近记录: |