先不多说,看代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
printf("A\n");
pid_t pid1 = fork();
if (pid1 < 0) {
fprintf(stderr, "fork error!\n");
exit(EXIT_FAILURE);
} else if (pid1 == 0) {
printf("B\n");
} else {
wait(NULL);
pid_t pid2 = fork();
if (pid2 < 0) {
fprintf(stderr, "fork error!\n");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
printf("C\n");
} else {
wait(NULL);
}
}
return 0;
}
如果把上面A后面的'\n'去掉,最后会得到不同的结果(当然,这里不是说有没有换行……-_-|||)
不去掉的话,结果大概像这样:
去掉的话,大概像这样:
嗯,问题来了,我们可以很明显的看出:
![](https://app.yinxiang.com/shard/s9/res/481bfd91-21bf-474d-9c04-7253a03f6385/Screenshot%20from%202013-11-02%2018%3A29%3A00.png?resizeSmall&width=786)
嗯,问题来了,我们可以很明显的看出:
- 后者多了两个看上去不应该存在的'A'
- 前者父进程的输出在子进程前面,后者父进程的输出在子进程的后面(单独的那个‘A’)
乍看上去感觉有点奇怪,但仔细想想的话其实可以发现:
- 关于第一点,既然是fork,那么就会把父进程的各种东西都复制过去(实际上并不是一开始就复制,而是直到写的时候才发生复制,不过在这里不影响),所以也会把缓冲区里面的东西也复制过去,此时:
-
- 前者因为加上'\n',所以printf会输出缓冲区内容并清空,所以fork的时候缓冲区没有内容
-
- 而后者只是把‘A’弄到缓冲区,却并没有直接输出并清空缓冲区,fork的时候'A'依然保留着,所以子进程的缓冲区也有'A',从而造成了多出来两个'A'的现象。
- 至于第二点,也是由于上面的原因,printf只是将‘A’弄到缓冲区,而没有直接输出并清空缓冲区,导致最后是在进程结束的时候才输出缓冲区的内容,而父进程结束最晚,所以输出也最晚,从而导致了第二点的现象!