【问题标题】:Fork(); method in C: determine order叉(); C中的方法:确定顺序
【发布时间】:2017-03-26 13:28:29
【问题描述】:

我试图了解叉子在 C 中是如何工作的,但我在某处误解了一些东西。

去年我遇到了一位教授给我的测试,但我无法回复: 我们有 3 个任务(进程或线程),伪代码如下:

Th1 { display "Hello 1" }
Th2 { display "Hello 2" }
Th3 { display "Hello 3" }

main() {
    Fork(Th1);Fork(Th2);Fork(Th3);
}

问题是:Which is the order of the execution of these tasks? Why?

我该如何回复这个问题?是否有任何指南或任何有用的资源可以让我了解分叉、信号量和内存分配的方式?

我是低级编程的真正新手。

【问题讨论】:

  • 顺序是随机的。因此,如果您需要强制执行特定顺序,则需要实现锁定机制,例如使用信号量。
  • 当然可以。我怎么知道?为什么?
  • fork 只是产生了一个新进程,由操作系统为其安排资源以及何时运行它。

标签: c memory fork


【解决方案1】:

您所询问的详细信息有意未指定。您应该想象它发生的方式是,在每次“fork”操作之后,父进程和子进程都同时运行,并且它们所做的事情之间没有排序,除非你明确地进行排序。

您展示的伪代码程序可以以任何顺序打印“Hello 1”、“Hello 2”和“Hello 3”,并且每次运行时它可能是不同的顺序,具体取决于系统其他地方发生的意外事故。

对比这个伪代码程序:

main { display "Hello main"; fork(Th1); }
Th1 { display "Hello 1"; fork(Th2); }
Th2 { display "Hello 2"; fork(Th3); }
Th3 { display "Hello 3"; }

这保证打印“Hello main”、“Hello 1”、“Hello 2”、“Hello 3”按此顺序。你明白为什么吗?

很遗憾,我无法为您指出清晰、简洁和在线的参考资料。 specification of fork里有这句话:

在 fork() 之后,父进程和子进程都应该能够在任一进程终止之前独立执行。

但你必须知道如何阅读标准语才能知道这意味着我上面所说的一切。我能想到的其他一切都是教科书长度,例如W. Richard Stevens 的Advanced Programming in the Unix Environment,您可能想看看您的图书馆是否有副本。

【讨论】:

  • 好的,非常感谢。是的,我想我明白了原因:这是因为 main() 首先调用了 fork(Th1)。 Th1() 正在打印“Hello 1”,然后调用 fork(Th2),它显示“Hello 2”,依此类推。
  • 根据底层细节,三个任务的输出可以完全混合,例如HeHelHllleolol32o1.
【解决方案2】:

fork 不是 C 的一部分。在一些直接支持 fork 概念的操作系统(尤其是 eunuchs 变体)中,它是一种系统服务。在其他操作系统中,fork 是一个模仿“fork 概念”的库调用。

问题是:这些任务的执行顺序是什么?为什么?

这是未定义的。创建的顺序将是 1、2、3,但它们执行的顺序无法预测,尤其是在多处理器系统中。

在分叉模型中,每个分叉都会创建父进程的副本。然后,孩子通常会加载一个新的可执行文件并运行它。在您的简单伪代码中,您可以在不运行新的可执行文件的情况下做您想做的事,但任何比打印消息更重要的事情都可能需要每个子进程都有一个单独的可执行文件运行。

由于程序的执行不是直线进行,因此您的排序问题受到了破坏。即使在单处理器系统中,1、2、3 也不太可能不间断地从头到尾运行,每次“显示”您的进程都可能将 CPU 让给另一个进程。您的进程也可能会产生页面错误。如果您确实加载了另一个可执行文件,那将增加可变性。

序列问题在多处理器系统中更为严重。假设您有四个处理器,并且每个子进程都分配到一个单独的进程的工作队列中。执行顺序取决于每个处理器工作队列前面发生的情况。

如果你在一个模仿太监的fork模型的系统上这样做,会有更大的可变性,因为进程复制语义会不同。

【讨论】:

    猜你喜欢
    • 2018-07-05
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多