【问题标题】:Fork in critical section临界区分叉
【发布时间】:2021-09-05 07:03:52
【问题描述】:

最近,在我接受的一次采访中,我们正在讨论关键部分。 问的问题是“what happens when we execute fork inside critical section? Will the resulting child process also execute the critical section simultaneously?” 我们讨论了各种可能性:

  1. 是的,两者可能同时执行关键部分
  2. fork() 系统调用可能会阻塞子进程,只允许父进程执行临界区。
  3. 编译器可能足够智能以识别此问题并可能引发编译错误。 不幸的是,我在互联网上找不到有关此的更多详细信息。 TIA。

编辑: 添加伪代码供参考:

semaphore s;
s.wait(); // lock
/* critical-section */
pid = fork(); /* what will happen here in child/parent process? */
s.signal(); // unlock

【问题讨论】:

  • 难道不依赖于信号量的实现吗?
  • 有不同的东西叫做“信号量”,有不同的语义。 POSIX 信号量、SysV 信号量、手写的东西?

标签: linux fork critical-section


【解决方案1】:

对于 Linux 信号量,sem_init 的第二个参数确定它是否是跨进程信号量。您将它们放在共享内存中,由fork 继承。

fork 不会尝试检查现有信号量,也不会尝试调整信号量计数。信号量可以有 >1 的计数,并允许许多运行线程。所以计数为 2 将允许两个线程运行 - fork 不会猜测。

[编辑] 下面的旧答案假设一个 Linux futex,它更像是一个关键部分。

“The”关键部分具有误导性。在分叉之后,两个进程都有自己的临界区。因此,您的 3 个选项都不适用。

【讨论】:

  • 好的。 “临界区”是指一组受信号量保护的代码。想象一下: semaphore s; s.等待(); // 临界区代码或资源 pid = fork(); s.信号();现在,在回复上述内容时,我认为会有一个完全不同的信号量,因此会有不同的临界区副本?我无法清楚地思考。提前感谢您的帮助。
【解决方案2】:

当我们在临界区执行 fork 时会发生什么?生成的子进程是否也会同时执行临界区?"

  1. 是的,两者可能同时执行关键部分
  2. fork() 系统调用可能会阻塞子进程,只允许父进程执行临界区。
  3. 编译器可能足够智能以识别此问题并可能引发编译错误。不幸的是,我找不到更多 互联网上有关此的详细信息。 TIA。

原则上,以上任何一个和更多都是可能的,但我所知道的任何系统都没有实现 (2) 和 (3)。特别是,由于您标记了 Linux,GLibc 的fork() 没有任何与信号量交互的特殊规定,GCC 不会以您的建议为由拒绝代码。 (有一个(系统 V)信号量调整的问题,但这并不直接相关。)

但是(1)也不完全正确。确实,如果fork() 成功,那么子进程将通过从分叉返回到临界区来开始执行。当父级仍在临界区中时,没有什么能特别阻止这种情况发生,因此 可能 两者同时在临界区中运行。另一方面,两个结果进程中的一个可能不会被安排实际执行任何指令,直到恰好在另一个进程退出临界区之后。这看起来很像 (2),尽管从技术上讲,这两个进程都没有被阻止。

然而,这只是涉及这种情况的问题的冰山一角。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-17
    • 2013-03-26
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多