标准I/O提供三种类型的缓冲:
1、全缓冲:(大小不定)
在填满标准I/O缓冲区后,才进行实际的I/O操作。术语冲洗缓冲区的意思是进行标准I/O写操作。程序结束也能冲洗缓冲区。
2、行缓冲:(大小不定)
在遇到换行符时,标准I/O库执行I/O操作。这种情况允许我们一次输入一个字符,但只有写了一行后才进行实际的I/O操作。
3、不带缓冲
进程中缓冲的猫腻:
fork.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
pid_t pid;
int length=0;
char buf[]="a write to stdout\n";
length=write(1,buf,strlen(buf));
if(length!=strlen(buf))
{
printf("write error\n");
}
printf("before fork\n");
pid=fork();
if(pid<0)
{
perror("fork");
}
else if(pid==0)
{
printf("in son process\n");
}
else
{
sleep(1);
printf("in father process\n");
}
return 0;
}
编译生成可执行程序,按如图执行见效果:
当重定向时write可以直接输出到文件中,printf由行缓冲变成了全缓冲,则“before fork”不能输出到文件中,只能在缓冲区等待
程序结束才能输出,所以子进程继承了父进程的缓冲区中的“before fork”所有重定向后的输出有2个“before fork”。
1、调用fork函数后,父进程打开的文件描述符都被复制到子进程中。在重定向父进程的标准输出时,子进程的标准输出也被重定向。
2、write函数是系统调用,不带缓冲。
3、标准I/O库是带缓冲的,当以交互方式运行程序时,标准I/O库是是行缓冲的,否则它是全缓冲的。