【发布时间】:2016-02-09 16:34:54
【问题描述】:
我正在了解fork(),但我的 ubuntu 出现了问题。我正在运行此代码:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
printf("--beginning of program\n");
int counter = 0;
pid_t pid = fork();
if (pid == 0)
{
// child process
int i = 0;
for (; i < 5; ++i)
{
printf("child process: counter=%d\n", ++counter);
}
}
else if (pid > 0)
{
// parent process
int j = 0;
for (; j < 5; ++j)
{
printf("parent process: counter=%d\n", ++counter);
}
}
else
{
// fork failed
printf("fork() failed!\n");
return 1;
}
printf("--end of program--\n");
return 0;
}
我知道父母和孩子应该不按特定顺序运行他们的代码,所以代码应该返回如下内容:
-beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
child process: counter=1
parent process: counter=4
child process: counter=2
parent process: counter=5
child process: counter=3
child process: counter=4
child process: counter=5
--end of program--
但是每次我运行程序时,它们似乎都以相同的顺序运行。这是我每次运行这个程序时得到的结果:
user@user-VirtualBox:~/Documents/S-O$ ./sample
--beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
parent process: counter=4
parent process: counter=5
--end of program--
user@user-VirtualBox:~/Documents/S-O$
child process: counter=1
child process: counter=2
child process: counter=3
child process: counter=4
child process: counter=5
--end of program--
似乎父母先完成,然后孩子开始。但我想那不是真的。请注意,第二个 shell 提示符是由程序本身打开的。对可能发生的事情有任何想法吗?
编辑:
如果我输入sleep(1),它就可以正常工作。我仍然认为毫不拖延地,它不应该总是具有相同的执行顺序。即使数到 100 也一样
【问题讨论】:
-
当您使用较大的数字时会发生什么?在每个循环中都在那里睡觉,看看会发生什么。
-
你试过数 > 5 吗?
-
当我使用更大的数字时,它会做同样的事情。
-
我怀疑您看到的序列化是基于标准输出的缓冲性质以及现代计算机数到五的速度。我采用了这段代码并没有缓冲标准输出,并将循环限制从 5 提高到 10K。然后它开始表现出来自子进程和父进程的一些 IO 交错。
-
@tripleee 我的父子计数都达到了 10000,并将标准输出从行缓冲修改为无缓冲
setvbuf(stdout,NULL,_IONBF,0);,并且孩子在 200 左右开始交错(在 2014 年中期 MBP 为 2.mumble赫兹)。有趣的是,删除setvbuf导致父子序列再次序列化。