fork()与输出缓冲区:一个有意思的坑
来源:互联网 发布:宇信数据科技有限公司 编辑:程序博客网 时间:2024/05/01 22:57
先不多说,看代码:
#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'去掉,最后会得到不同的结果(当然,这里不是说有没有换行……-_-|||)
不去掉的话,结果大概像这样:
去掉的话,大概像这样:
嗯,问题来了,我们可以很明显的看出:
嗯,问题来了,我们可以很明显的看出:
- 后者多了两个看上去不应该存在的'A'
- 前者父进程的输出在子进程前面,后者父进程的输出在子进程的后面(单独的那个‘A’)
乍看上去感觉有点奇怪,但仔细想想的话其实可以发现:
- 关于第一点,既然是fork,那么就会把父进程的各种东西都复制过去(实际上并不是一开始就复制,而是直到写的时候才发生复制,不过在这里不影响),所以也会把缓冲区里面的东西也复制过去,此时:
- 前者因为加上'\n',所以printf会输出缓冲区内容并清空,所以fork的时候缓冲区没有内容
- 而后者只是把‘A’弄到缓冲区,却并没有直接输出并清空缓冲区,fork的时候'A'依然保留着,所以子进程的缓冲区也有'A',从而造成了多出来两个'A'的现象。
- 至于第二点,也是由于上面的原因,printf只是将‘A’弄到缓冲区,而没有直接输出并清空缓冲区,导致最后是在进程结束的时候才输出缓冲区的内容,而父进程结束最晚,所以输出也最晚,从而导致了第二点的现象!
- fork()与输出缓冲区:一个有意思的坑
- fork与输出缓冲区
- fork(2), stdio 行/块缓冲区,子进程为何输出fork()之前的东西
- fork()里的一个小疑问(缓冲区)
- 有意思的进程创建函数fork() && fork() || fork() .
- 输入与输出缓冲区的概念
- 输入 /输出 缓冲区 与 数组的常识
- 关于fork一些有意思的问题
- fork()子进程复制父进程的缓冲区的一个例子
- fork与vfork遇到的一个问题
- 输出缓冲区的管理
- 输出缓冲区的刷新
- 输出缓冲区的管理
- 输出缓冲区的管理
- PHP的输出缓冲区.
- PHP的输出缓冲区
- PHP的输出缓冲区
- PHP的输出缓冲区
- python 学习笔记 6 -- 异常处理
- yymore & yyless
- 对一个vim 函数的详细注释。
- AAC ADTS LATM 格式分析
- C#与JavaScript互相调用
- fork()与输出缓冲区:一个有意思的坑
- android.app.Activity//
- 使用waveOut接口在Windows中播放声音
- 读取jar包所在目录和jar包内文件
- Linux make编译报错:undefined reference to `vtable for XXX '
- 全局变量和静态变量的初始化问题
- JavaScript—window对象使用
- Java多线程并发访问解决方案
- iOS获取本地通信录、添加联系人信息