c - 在终端上使用 fork 时,要打印的文本正在命令行上打印,而不是打印空格

标签 c terminal 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;
}

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

最佳答案

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

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

  1. 打印“来自家长的问候”
  2. 退出返回调用者
  3. 调用者打印下一个提示

在 child 身上,我们会发生这些事情

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

    但是由于我们有两个控制线程和一个竞争条件,因此根据不同打印步骤的交错方式,我们可以看到不同的结果:

       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 microkernel ,这改变了一些东西。)

    <小时/>

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

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

    假设您经营一家治疗中心。假设你有一个“尖叫室”,人们可以随意大声尖叫,以发泄他们的挫败感。因此,当您听到那个房间里传来尖叫声时,您知道这是您的一名患者发出的,但如果那里没有患者,您就不会听到任何尖叫声。

    有一天,一个女人进来,她压力很大,你把她带进尖叫室,你听到很多尖叫声,但过了一会儿她回来了,你移动了房间里的小标志。门从“有人”回到“无人”。但随后,令您惊讶的是,您听到门后传来另一声尖叫(更像是哭声)......

    哦,我有没有提到,这位女士一开始承受如此大的压力是因为她怀孕了,即将分娩?

    关于c - 在终端上使用 fork 时,要打印的文本正在命令行上打印,而不是打印空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57513297/

    相关文章:

    linux - Emacs 在 su 到 root 后加载用户配置文件

    c - 理解这些过程如何运作的问题

    c++ - 使用 shmat 和 shmget 与 forks 相乘矩阵

    c - 简单的C程序无法运行

    c - Mac OS 更新后,Strcpy 不适用于循环的第一行

    c - 这段代码中创建了多少个进程?

    c - 同步2个进程

    c - Linux 克隆调用的最小堆栈大小?

    python - 如何在终端中以 'page' 打印带有 html 内容的 python 变量?

    terminal - "which nvm"命令(通过 Homebrew 软件安装的 nvm)不返回路径