在fork()创建子进程过程中发现了一个有趣的现象。

源代码

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<unistd.h>
 4 int main(){
 5     printf("before fork %d\n",getpid());
 6     pid_t pid= fork();
 7     if(pid==-1){
 8         perror("fork error");
 9         exit(1);
10     }
11     else if(pid==0){
12         printf("i am  child,my pid=%d\n",getpid());
13     }
14     else if(pid>0){
15         printf("i am parent,my pid= %d\n",getpid());
16     }
17     printf("after fork-------%d\n",getpid());
18     return  0;
19 }

  理论上,“before fork”这段话应该只打印一次,在终端上确实只打印了一次。但是如果把输出结果重定向到另一个文件中,会发现“before fork”打印了两次。

//file
before fork 4392
i am parent,my pid= 4392
after fork-------4392
before fork 4392
i am  child,my pid=4393
after fork-------4393

  这是因为往屏幕上打印是行缓冲模式,在输入输出时遇到'\n'时,会自动刷新缓冲区。当我们把输出的数据重定向到文件中,在这种情况下,是全缓冲模式,遇到“\n”不会刷新缓冲区。当“befor fork\n”进入缓冲区时并没有刷新,紧接着进行fork()了子进程,那么在父子进程的缓冲区都有一个"befor fork\n"

  解决办法就是在源文件fork()函数执行之前添加“fflush()”刷新流。

  在使用exec函数族的时候出现同样的现象

1     puts("begin!");
2     //fflush(NULL);
3     execlp("ls","ls","-l",NULL);
4     perror("execlp() is error\n");
5     exit(1);
6     puts("end!");
7     exit(0);

输出到终端

begin!
总用量 28
-rwxrwxr-x 1 tx tx 16824 1月  31 23:50 exe
-rw-rw-r-- 1 tx tx   183 1月  31 23:49 exe.c
-rw-rw-r-- 1 tx tx   154 1月  31 23:11 out

输出到文件,发现并没有begin

总用量 24
-rwxrwxr-x 1 tx tx 16824 1月  31 23:50 exe
-rw-rw-r-- 1 tx tx   183 1月  31 23:49 exe.c
-rw-rw-r-- 1 tx tx     0 1月  31 23:50 out

  这是因为,begin放在缓冲区中还没有来及往外输出,执行exec()会有一个新的进程映像来替代原有的进程印象。所以在执行exec函数之前要使用fflush()函数刷新所有该刷新的流。