fork()ed多线程进程中的同步

时间:2013-09-06 21:30:42

标签: multithreading synchronization thread-safety fork

如果我有一个创建N个线程的进程;即T1 .... Tn。假设N个线程正在使用锁L来在它们之间进行同步。如果此过程调用fork()

  1. 创建的新子进程有N个线程还是只有一个线程?来自this question,看起来就像只有1个帖子
  2. 将锁L复制到具有相同值的新内存(物理)位置,对吧?
  3. 如果对问题(1)的回答是只复制了1个线程,那么如果T1已锁定L并且从另一个线程T2调用fork(),则新进程中会发生什么。 L会永远被锁定吗?

2 个答案:

答案 0 :(得分:1)

新进程最初只有一个正在运行的线程。该进程的互斥锁副本永远被锁定,除非明确重新初始化或除非互斥共享互斥锁(属性PTHREAD_PROCESS_SHARED,并非所有地方都支持)。

以下是关于这种情况的规范,在其对pthread_atfork()的讨论中说,部分介绍了哪种功能是为了解决这种不愉快:

  

考虑一个线程锁定了互斥锁和状态的情况   另一个线程调用时,该互斥锁覆盖的内容不一致   叉子()。在孩子中,互斥锁处于锁定状态(由a锁定   不存在的线程,因此永远不会被解锁)。让孩子简单地重新初始化互斥体是不能令人满意的,因为这种方法不能解决关于如何纠正或以其他方式处理孩子不一致状态的问题。

答案 1 :(得分:0)

  1. 除非你在生成线程之前调用fork(),否则它只会在它自己的上面。分叉不会复制子线程/进程。
  2. 进程堆中的数据在分叉时被复制到新进程(很可能使用copy-on-write)如果锁存储在堆中,它将获得它自己的副本,因为进程有自己的堆。 / LI>
  3. 使用常规锁(而不是信号量)任何线程都可以锁定/解锁它。