C fork()作为循环条件语句
我有下面的一段代码,我想解释这段代码中fork调用的行为,break条件作为命令行参数给出C fork()作为循环条件语句,c,fork,C,Fork,我有下面的一段代码,我想解释这段代码中fork调用的行为,break条件作为命令行参数给出 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i = 0; char *ptr; int x = strtol(argv[1], &ptr, 10); while (fork())
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i = 0;
char *ptr;
int x = strtol(argv[1], &ptr, 10);
while (fork())
{
if (i == x)
{
break;
}
printf("PID: %d, PPID: %d, i = %d\n", getpid(), getppid(), i++);
}
return 0;
}
我认为应该发生的是,fork调用将执行一次,创建子进程和父进程,将非零进程id返回给父进程,将零返回给子进程。
零值应解释为false,并且只有父进程将继续打印一次,然后将i的值增加到1,然后再次重复创建另一个子进程,该子进程将再次不进入循环,并且当i=1时,它将跳出循环,那么为什么我看到的是2行而不是1行?
更高的i值的输出更令人费解,但可以预见。
有人能解释一下我的假设中的缺陷吗?您看到的重复消息来自stdio缓冲,而且printf在默认情况下并不实际打印-它只是将一些内容放入缓冲区,稍后在进程退出时刷新缓冲区时打印,如果不是之前,则从显式刷新或缓冲区填充开始 最重要的是,当您分支一个子级时,该子级将获得所有父级状态(包括所有stdio缓冲区)的副本。因此,如果在stdio缓冲区中有任何未刷新的数据,那么这些数据将被复制并最终写入两次—一次由父级写入,一次由子级写入 您可以通过放置一个显式的fflushstdout来避免这种情况;在printf之后
使这一点更加复杂的是,stdio还支持称为行缓冲模式的东西,在这种模式下,它将在每次写入换行时自动刷新文件。在某些系统上,这是在标准输出上默认设置的,但在其他系统上,它是由实现定义的。您可以通过使用setLineBufstOut在标准输出上显式设置行缓冲模式来利用这一点;在主函数的开头。您看到的重复消息来自stdio缓冲,而且printf在默认情况下并不实际打印-它只是将一些内容放入缓冲区,稍后在进程退出时刷新缓冲区时打印,如果不是之前,则从显式刷新或缓冲区填充开始 最重要的是,当您分支一个子级时,该子级将获得所有父级状态(包括所有stdio缓冲区)的副本。因此,如果在stdio缓冲区中有任何未刷新的数据,那么这些数据将被复制并最终写入两次—一次由父级写入,一次由子级写入 您可以通过放置一个显式的fflushstdout来避免这种情况;在printf之后 使这一点更加复杂的是,stdio还支持称为行缓冲模式的东西,在这种模式下,它将在每次写入换行时自动刷新文件。在某些系统上,这是在标准输出上默认设置的,但在其他系统上,它是由实现定义的。您可以通过使用setLineBufstOut在标准输出上显式设置行缓冲模式来利用这一点;在你的主要职能的开始
PID: 684067, PPID: 14913, i = 0
PID: 684067, PPID: 14913, i = 0