转自:https://blog.csdn.net/shanshanpt/article/details/7385649
Linux中有缓冲IO,对应于每个打开的文件都会有一片缓冲区。每次写文件时都会写入到内存中的缓冲区,等到满足一定条件时,(例如缓冲区已满,或遇到特定字符,如"\n"),再将缓冲区的内容一次性写入文件。
printf有行缓冲
例子1,行缓冲没满,没有\n
printf("Hello world");
由于没有换行符,并且缓冲区没满,printf函数只把“Hello world”写入到了缓冲区,不会输出
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main( int argc, char ** argv )
{
pid_t pid;
int ret;
printf("Hello world");//此刻并没有输出,而是写到了parent的缓冲区中
ret = fork(); //子进程fork了父进程的缓冲区,所以子进程的缓冲区也有Hello world
switch( ret )
{
case -1:
printf("Error...\n");
exit( EXIT_FAILURE );
case 0:
printf(" I am child!\n"); //\n输出子进程缓冲区的内容,清空缓冲区,即
//Hello world I am child!
break;
default:
printf(" Parent too..\n");//\n输出父进程缓冲区的内容,清空缓冲区
//即Hello world Parent too..
break;
}
return 0;
}
输出:
Hello world Parent too..
Hello world I am child!
例子2,行缓冲满,没有\n
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main( int argc, char ** argv )
{
pid_t pid;
int ret;
//printf("Hello world");
printf("..onsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvaonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvls");
//行缓冲已满,输出缓冲区的所有字符,剩下的fork给子进程
ret = fork();
switch( ret )
{
case -1:
printf("Error...\n");
exit( EXIT_FAILURE );
case 0:
printf(" I am child!\n");
break;
default:
printf(" Parent too..\n");
break;
}
return 0;
}
输出:
..onvdkakvnaslkbasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvakaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvaonsdnvasldvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnaslddvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvadvjnasldkvnaslkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnsldvjnasldkvnasldkvnkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvls Parent too..
asldkvnasldkvnsldvjnasldkvnasldkvnkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvls I am child!
可以看到行缓冲满了情况下,parent输出了大部分字符,child只fork了一小段parent行缓冲剩余的字符
exit()和_exit()
exit与_exit的区别在于,exit在进程结束前会把文件缓冲区中的内容输出(写会文件),而_exit则不会,所以缓存区的内容会丢失!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main( int argc, char ** argv )
{
pid_t pid;
int ret;
ret = fork();
switch( ret )
{
case -1:
printf("Error...\n");
exit( EXIT_FAILURE );
case 0:
printf(" I am child!\n");
printf("Hello world in child");
_exit(0);
break;
default:
printf(" Parent too..\n");
printf("Hello world in parent");
exit(0);
break;
}
return 0;
}
输出:
Parent too..
Hello world in parent I am child!
可以看到
printf("Hello world in child");
并没有输出,因为_exit()不会吧缓冲区中的内容写到文件中。