printf输出条件:
(1) 调用fflush;
(2) 缓冲区满了;
(3) 遇到\n \r这些字符
(4) 遇到scanf这些要取缓冲区的;
(5) 线程或者进程退出;
fork之后会拷贝父进程的缓冲区;
代码:
1 #include <unistd.h> 2 #include <stdio.h> 3 4 5 int glob = 6; 6 char buf[ ] = "a write to stdout\n"; 7 8 int main() 9 { 10 int var; 11 pid_t pid; 12 13 var = 88; 14 15 if (write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) - 1){ 16 perror("write error\n"); 17 return -1; 18 } 19 20 printf("before fork\n"); 21 22 if ((pid = fork()) < 0){ 23 perror("fork error\n"); 24 return -1; 25 } else if (pid == 0){ 26 glob++; 27 var++; 28 } else { 29 sleep (2); 30 } 31 32 printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); 33 34 return 0; 35 }
结果:
[root@AY1404041716143649d3Z forkPrintf]# gcc forkPrintf.c -o forkPrintf [root@AY1404041716143649d3Z forkPrintf]# ./forkPrintf a write to stdout before fork pid = 17098, glob = 7, var = 89 pid = 17097, glob = 6, var = 88 [root@AY1404041716143649d3Z forkPrintf]# ./forkPrintf > tmp.out [root@AY1404041716143649d3Z forkPrintf]# cat tmp.out a write to stdout before fork pid = 17106, glob = 7, var = 89 before fork pid = 17105, glob = 6, var = 88
(1) 第一次输入到控制台,write无缓冲直接输出,printf("before fork\n")存在\n行缓冲标识直接输出,而子进程拷贝父进程代码段,随后也会输出最后的printf;
(2) 第二次输入到文件,write无缓冲直接输出,printf("before fork\n")成了全缓冲的并没有输出,子进程拷贝了父进程的缓冲区和代码段,所以当父子进程退出时,刷新缓冲区,均有两条printf输出;