【问题标题】:Irregular result in zombie example僵尸示例中的不规则结果
【发布时间】:2017-07-27 20:52:41
【问题描述】:

我无法理解这段代码的行为:

#include <stdio.h>
#include <stdlib.h>
int main() {
int nr;
nr = fork();
  if (nr == 0) {
    /* Child process */
    printf("Child process, fork return value %d\n", nr);
    exit(0);
  } else {
    /* Parent process */
    printf("Parent process, fork return value: %d\n", nr);
    exit(0);
  }
}

在 Unix shell 中运行时,我得到以下结果:

Parent process, fork return value: 343
Child process, fork return value: 0

但有时它只给我这个结果而没有任何 shell 提示:

Child process, fork return value: 0

我知道它可以通过父进程中的 wait() 函数来解决。但我想知道:

为什么结果不规则?有人可以解释发生了什么吗?子进程变成僵尸,父进程为什么不调用printf()函数?

【问题讨论】:

  • 我在 Linux 上试过这个,但无法观察到你描述的内容。相反,我总是收到两条消息。我什至试图让父亲和/或孩子睡一觉,但除了预期的延误外,没有任何改变。同样从理论上讲,我无法为您的观察找到任何解释。您介意告诉我们这是在您的哪个系统上发生的吗?
  • 父进程也应该打印消息。僵尸进程是指子进程在父进程对其执行wait 之前完成执行。 printf 在变为zombie process 之前执行。无论子进程如何,父进程都应该打印它的消息......它们在 fork 共享相同的stdout 之后是独立的进程,因为你没有重定向。

标签: linux shell unix process operating-system


【解决方案1】:

有 2 个问题需要考虑: 1) 有你可能想要刷新的标准输出缓冲

fflush(stdout);

2) 多任务处理有时会以意想不到的顺序执行 发生这种情况时,我会得到类似的结果:

/tmp$ ./a.out
Parent process, fork return value: 24049
/tmp$ Child process, fork return value 0

如您所见,提示位于子进程输出的开头,它并没有完全丢失,只是不在您期望的位置。

使用此代码,我尝试了几次,但从未在子级或父级的输出行中出现提示:

#include <stdio.h>
#include <stdlib.h>
int main() {
int nr;
nr = fork();
  if (nr == 0) {
    /* Child process */
    printf("Child process, fork return value %d\n", nr);
    fflush(stdout);
    exit(0);
  } else {
    /* Parent process */
    printf("Parent process, fork return value: %d\n", nr);
    fflush(stdout);
    sleep(1);
    exit(0);
  }
}

【讨论】:

  • 这个答案是错误的,因为执行顺序无关紧要,两条消息都应该打印到stdout。 OP 观察到的是父母没有打印。
  • 没有什么 OP 可能观察到的是乱序打印露水到多任务处理。我已经重现了该错误,并且可以发现其中一条输出行中显示了提示。
  • 如果他错过了整行,我很有可能 fflush 会解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多