【问题标题】:Forking a process prints differently each time每次分叉一个进程的打印方式都不同
【发布时间】:2018-09-24 18:29:39
【问题描述】:

我有一段代码可以在分叉后打印出 PID,并且只是一个基本的用户输入内容,但是每次我运行脚本时,有时它都会按预期运行,并且在一个命令中全部打印出来,然后在下一次孩子打印它的 PID,它在下一行打印它并使终端处于您需要按 Enter 键才能继续的状态。我已经研究了这个网站,关于人们在什么情况下会脸红,我在各处都添加了这些内容,但我仍然无法让它发挥作用。

我的代码:

#include <unistd.h>
#include <stdio.h>
#include "sys/types.h"
int main(){
int pid;
int userInput;

    printf("Please enter a number: ");
    userInput = getchar();

    printf("\nYou entered: ");
    putchar(userInput);
    printf ("\n");
    fflush(0);

    pid = fork();
    if (0 == pid)
    {
        printf ("I am the child process, my PID is %d \n", getpid());
        fflush(0);
    }
    else
    {
        printf ("I am the parent process, my PID is %d \n", getpid());
        fflush(0);
    }
return 0;
}

当我运行它几次时会发生这种情况:

有人能指出我哪里出错以及如何改正吗?

谢谢!

【问题讨论】:

  • 请注意,fflush(0) 是未定义的行为。 fflush() takes a FILE * 参数,0NULL 指针常量。
  • 这看起来像 C.
  • "无法让它工作。" 到底是什么你想达到什么目的?

标签: c++ fork flush


【解决方案1】:

因为父进程和子进程之间没有调度和优先级的保证。

您观察到的通常情况是以下事件:

  • 父进程打印它的行
  • 在后台运行的子进程打印它的行
  • 命令提示符返回(作为父进程的结果 退出)

但你有时会观察到:

  • 父进程打印它的行
  • 命令提示符返回(作为父进程的结果 退出)
  • 在后台运行的子进程在命令提示符顶部打印其行 -

虽然在您的示例系列运行中未显示,但以下顺序也是有效且可能的。

  • 在后台运行的子进程首先打印它的行。
  • 父进程在子进程之后打印它的行
  • 命令提示符返回(作为父进程的结果 退出)

唯一可以保证的因果顺序是在父进程打印其行并退出后出现的命令提示符。操作系统如何安排派生的子进程相对于父进程运行是不确定的。子进程可以先打印,最后打印,也可以在父进程的事件之间打印。

如果您想保证子进程和父进程之间打印语句的顺序,则需要使用跨进程同步原语在子进程和父进程之间进行协调。

【讨论】:

    【解决方案2】:

    每次分叉进程的打印方式都不同 ?当您执行fork() 时,第一个parent 将运行并在foreground 中运行,然后child 将运行并在background 中运行。现在你的理由会有所不同,因为如果前台进程完成,后台进程会进入前台并显示其输出,反之亦然。

    如果命令提示符是空闲的,即如果父进程完成,那么子进程将进入前台并显示其输出,shell 不会停止子进程在前台执行。

    请注意,子进程和父进程的执行顺序可能因操作系统而异

    【讨论】:

    • 吹毛求疵:孩子或父母先运行很大程度上取决于操作系统,而不是您可以依赖的东西。
    • 观察到的行为等于保证行为。
    • 我能以某种方式强制子进程到前台吗?
    • 方法不正确,但有一个技巧,将parent 中的sleep()child 进行比较。这样parents 完成了1st 而不是child 现在foreground 是免费的,所以child 输出将泵入command prompt
    • 请注意,在特定持续时间内,child 将处于 orphan 状态
    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多