c - 为什么这段代码有时只调用 printf() 一次而不是两次?
问题描述
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t pid;
pid = fork();
fork();
if (pid > 0) {
printf("Hello, World!\n");
}
return EXIT_SUCCESS;
}
当上面的代码运行时,它会打印以下输出,这是预期的:
Hello, World!
Hello, World!
但有时我再次执行代码后会得到以下输出:
Hello, World!
为什么代码有时只打印一次消息?
这只发生在程序在 IDE 的终端或类似 onlinegdb 的环境中运行时。
当程序从交互式 shell 启动时,总是会出现“Hello, World!”这两个预期行。被打印。
解决方案
TL; DR 分叉孩子和退出之间的竞争条件
根据子级或父级在(第二个)分叉之后是先运行,父级可以打印消息并退出,IDE 可以检测到它已退出并在子级运行之前关闭所有内容,并且打印它的消息。
从 bash 运行时不会发生这种情况,因为即使发生这种情况,孩子仍然能够输出它的消息。理论上,这可能会在 shell 打印下一个提示符后发生,但这似乎极不可能。
要记住的重要一点是,您的程序总是由某些东西(shell 或和 IDE 或其他)运行,并且某些东西会等待它退出,但不会等待您可能分叉的任何孩子。因此,如果您想确保您的孩子完成,您需要在退出之前等待他们。
推荐阅读
- r - 如果我们同时将“字符”和“数字”类型的结果的 ifelse 放在一起,为什么 mutate 不起作用?
- php - 如何在 kubernetes 中拥有可自动扩展的 Laravel API
- mongodb - MongoDB:处理对于 Int64 来说太大的整数
- openlayers - OpenLayers 3 - 仅为特定 bbox 提供 OSM 底图图块
- sql - 在包含多个相关项的 sql 查询中返回 json
- c++ - 不能在带有 vs2017 的 linux 子系统上包含标头
- javascript - 为什么绑定参数不指向实际的函数参数
- python - FileNotFoundError 但文件存在
- vue.js - Nuxt 无法更改数据变量
- c - 覆盖函数返回地址时在 macOS 上发生意外崩溃