当前位置: 技术问答>linux和unix
fork 函数问题,UNIX环境高级编程里面143页的问题
来源: 互联网 发布时间:2015-12-08
本文导语: #include #include #include #include #include int glob = 6; char buf[] = "sdtoutn"; int main(void) { int var; pid_t pid; var = 88; if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1 ) printf("write ...
#include
#include
#include
#include
#include
int glob = 6;
char buf[] = "sdtoutn";
int
main(void)
{
int var;
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1 )
printf("write error");
printf("befor forkn");
if ( (pid = fork()) d
/home/test$ cat d
sdtout
befor fork
pid = 30410, glob =7, var = 89
before exit
befor fork
pid = 30409, glob =6, var = 88
before exit
还是不明白为什么这两种方式输出的before fork 次数不一样。
书上的解释没有看明白
#include
#include
#include
#include
int glob = 6;
char buf[] = "sdtoutn";
int
main(void)
{
int var;
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1 )
printf("write error");
printf("befor forkn");
if ( (pid = fork()) d
/home/test$ cat d
sdtout
befor fork
pid = 30410, glob =7, var = 89
before exit
befor fork
pid = 30409, glob =6, var = 88
before exit
还是不明白为什么这两种方式输出的before fork 次数不一样。
书上的解释没有看明白
|
这个程序的关键之处在于理解函数printf,它是一个带缓冲的函数。
在标准输出到终端设备的时候,printf在三种情况下会立即输出到终端:
1、在字符串结尾带有换行符n
2、用强行输出函数fflush
3、在缓冲区中缓冲的数据已经满的时候。
在这三种情况下会立即输出到终端设备(注意这是讲的是终端设备),否则的话就暂存在缓冲区中,等待以上三个条件之一满足的时候再执行输出到终端,并清空缓冲区。
在执行a.out > d的时候执行了输出重定向(一般用dup2实现),这时的输出设备不再是标准终端设备(如显示器),所以在这种情况下printf会把输出的字符串缓存在缓冲区里,而不会立即输出。在执行fork之后,父子进程各有了一份该缓冲区的缓存内容,所以第二个"before fork"是由父进程的中相应的缓存内容中打印出来的。
而在直接执行a.out的时候,是直接输出到标准终端设备的(因为满足了条件一后面有n),并且清空了缓存,所以只打印了一个"before fork"。
可是为什么不会出现两个"stdout"呢?因为write函数是不带缓存的,是直接输出的,也就没有了以上的问题。
在标准输出到终端设备的时候,printf在三种情况下会立即输出到终端:
1、在字符串结尾带有换行符n
2、用强行输出函数fflush
3、在缓冲区中缓冲的数据已经满的时候。
在这三种情况下会立即输出到终端设备(注意这是讲的是终端设备),否则的话就暂存在缓冲区中,等待以上三个条件之一满足的时候再执行输出到终端,并清空缓冲区。
在执行a.out > d的时候执行了输出重定向(一般用dup2实现),这时的输出设备不再是标准终端设备(如显示器),所以在这种情况下printf会把输出的字符串缓存在缓冲区里,而不会立即输出。在执行fork之后,父子进程各有了一份该缓冲区的缓存内容,所以第二个"before fork"是由父进程的中相应的缓存内容中打印出来的。
而在直接执行a.out的时候,是直接输出到标准终端设备的(因为满足了条件一后面有n),并且清空了缓存,所以只打印了一个"before fork"。
可是为什么不会出现两个"stdout"呢?因为write函数是不带缓存的,是直接输出的,也就没有了以上的问题。