首页 > 解决方案 > 在终端上使用 fork 时,要打印的文本正在命令行上打印,而不是打印空间

问题描述

因此,在 ubuntu 终端中,当我使用 fork 运行一段简单的代码从子进程和父进程打印时,终端会在命令行上而不是在它之前打印子进程的打印语句。我想知道是否有办法解决它。

我对使用系统调用有点陌生,所以我真的没有尝试很多事情

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]){
    printf("(%d) Start\n", (int)getpid());
    int rc = fork();
    if(rc < 0 ){
        fprintf(stderr, "Error\n");
        exit(1);
    }
    else if(rc == 0){
        printf("(%d) Hello from the child, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
    }
    else{
        printf("(%d) Hello from the parent, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
    }
    return 0;
}

我希望打印的语句都在两个命令行之间,但最后一行一直打印在命令行上:

标签: cterminalfork

解决方案


这是竞态条件的经典示例。在fork调用之后,根据定义,您拥有两个独立的进程和两个控制线程。从理论上讲,它们是并行运行的。(在多处理器或多核机器上,它们实际上可能并行运行。)

在父级中,我们发生了这些事情:

  1. 打印“来自父母的你好”
  2. 退出回调用者
  3. 来电者打印下一个提示

在孩子身上,我们发生了这些事情

  1. 打印“来自孩子的你好”
  2. 出口

它是调用 shell 的子进程的父进程(在此上下文中)。所以shell正在等待的是父进程;父进程的退出(第 2 步)将触发下一个 shell 提示符的打印(第 3 步)。说孩子退出后会发生什么会更复杂,但由于它不会导致打印任何内容(或我们可以看到的任何内容),所以它最终并不重要。

但是由于我们有两个控制线程和一个竞争条件,我们可以看到不同的结果,具体取决于各种打印步骤的交错方式:

   thread of control #1           thread of control #2
   ------ -- ------- --           ------ -- ------- --
1. Hello from the parent
                               4. Hello from the child
3. next shell prompt

或者

1. Hello from the parent
3. next shell prompt
                               4. Hello from the child

或者可能

                               4. Hello from the child
1. Hello from the parent
3. next shell prompt

但是你得到的这些结果中的哪一个实际上取决于任何事情。(这是竞争条件的本质。)所以我对你教授的计算机表现出不同的行为并不感到惊讶。(一方面,虽然 MacOS 确实非常像 Unix,但它基于底层的Mach 微内核,这改变了一些东西。)


如果你仍然不满意,这里有一个——可能是牵强的——类比。

听起来您想在程序(整个程序)完成之前不应该返回另一个 shell 提示符。听起来您认为“程序”在完成后应该不可能打印任何内容,也就是说,在您看到下一个表明它已完成的 shell 提示符之后。

假设您经营一个治疗中心。假设您有一个“尖叫室”,人们可以在其中大声尖叫,以发泄他们的挫败感。所以当你听到那个房间里的尖叫声时,你就知道是你的一个病人发出的,但是如果那里没有病人,你就不会期望听到任何尖叫声。

所以有一天一个压力很大的女人进来了,你把她带到尖叫的房间里,你听到了相当多的尖叫声,但过了一会儿她又回来了,你把门上的小标志从“占用”回到“未占用”。但是,令你惊讶的是,你听到门后传来另一声尖叫(更像是哭声)......

哦,我有没有提到这个女人一开始压力很大的原因是她怀孕了,快要生了?


推荐阅读