fork()与输出缓冲区:一个有意思的坑

先不多说,看代码:

#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'去掉,最后会得到不同的结果(当然,这里不是说有没有换行……-_-|||)

不去掉的话,结果大概像这样:


去掉的话,大概像这样:

嗯,问题来了,我们可以很明显的看出:
  1. 后者多了两个看上去不应该存在的'A'
  2. 前者父进程的输出在子进程前面,后者父进程的输出在子进程的后面(单独的那个‘A’)
乍看上去感觉有点奇怪,但仔细想想的话其实可以发现:
  • 关于第一点,既然是fork,那么就会把父进程的各种东西都复制过去(实际上并不是一开始就复制,而是直到写的时候才发生复制,不过在这里不影响),所以也会把缓冲区里面的东西也复制过去,此时:
    • 前者因为加上'\n',所以printf会输出缓冲区内容并清空,所以fork的时候缓冲区没有内容
    • 而后者只是把‘A’弄到缓冲区,却并没有直接输出并清空缓冲区,fork的时候'A'依然保留着,所以子进程的缓冲区也有'A',从而造成了多出来两个'A'的现象。
  • 至于第二点,也是由于上面的原因,printf只是将‘A’弄到缓冲区,而没有直接输出并清空缓冲区,导致最后是在进程结束的时候才输出缓冲区的内容,而父进程结束最晚,所以输出也最晚,从而导致了第二点的现象!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值