0

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

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

2 回答 2

1

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

以下是规范在讨论pthread_atfork()时对这种情况的说明,该函数的引入部分是为了解决这种不愉快的问题:

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

于 2013-09-06T22:00:25.923 回答
0
  1. 除非您在生成线程之前调用 fork(),否则它将是独立的。分叉不会复制子线程/进程。
  2. 进程堆中的数据在分叉时被复制到新进程(很可能使用写时复制)如果锁存储在堆中,它将获得自己的副本,因为进程有自己的堆。
  3. 使用常规锁(而不是信号量)任何线程都可以锁定/解锁它。
于 2013-09-06T21:37:22.420 回答