fork是unix下创建子进程的函数
pid_t fork(void); //创建一个进程,父进程返回值为子进程pid,子进程返回值为0
当我们运行如下代码时,
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/wait.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
int main(){
//int fd=open("a.txt",O_CREAT|O_RDWR,0666);
//dup2(fd,STDOUT_FILENO);
printf("hello\n");
pid_t pid=fork();
if(pid<0){
perror("fork fail");
exit(1);
}
else if(pid==0){
printf("world\n");
exit(0);
}
else wait(0);
return 0;
}
容易知道终端输出结果如下
hello
world
但当我们删去前两行注释,把标准输出重定向到a.txt文件(即把printf输出内容输出到a.txt文件),再次运行,查看a.txt文件结果发现,内容如下
hello
world
hello
为什么会多出一个hello呢?怎么会是呢?
这涉及到缓冲区的问题,当调用printf时,要输出的内容并不是直接输出到目标文件中,而是放入缓冲区里,当达到一定条件时才把缓冲区内容写入文件中,当标准输出连到终端设备,他是行缓冲的(即遇到换行符\n时,将缓冲区内容写入终端,然后清空缓冲区),而当标准输出连到其他文件时,他是全缓冲的(只有当进程结束后才冲洗缓冲区)。
因此当我们重定向标准输出后,调用第一个printf(“hello\n”),这时缓冲区内容为hello\n,并不写入文件,因为进程还未结束。随后调用fork创建子进程,fork会复制父进程缓冲区,那么子进程的缓冲区在创建时就有hello\n内容,随后再调用printf(“world\n”)后,子进程结束前会将缓冲区内容输出到文件,所以有了a.txt文件头两行。父进程调用wait等待子进程结束,然后父进程结束前也把缓冲区内容“hello\n”写入文件中,所以就有了a.txt第三行hello。