write/printf同时使用导致输出乱序问题
写套接字io时,发现一个神奇的现象,控制台输入输出乱序
环境为ubuntu16.04
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
char buf[10]="";
char buf2[10]="dddp\n";
fd_set rdfds;
struct timeval tv;
int ret;
FD_ZERO(&rdfds);
FD_SET(0,&rdfds); //文件描述符0表示stdin键盘输入
tv.tv_sec = 3;
tv.tv_usec = 500;
ret = select(1,&rdfds,NULL,NULL,&tv);//第一个参数是监控句柄号+1
if(ret<0)
printf("selcet error\r\n");
else if(ret == 0)
printf("timeout \r\n");
else
printf("ret = %d \r\n",ret);
if(FD_ISSET(0,&rdfds)){ //监控输入的确是已经发生了改变
printf("reading");
read(0,buf,4); //从键盘读取输入
}
write(1,buf,strlen(buf)); //在终端中回显
printf(" %d \r\n",strlen(buf));
return 0;
}
上面的结果输出正常顺序应该是
假如控制台输入ssss
运行结果应该为
ret=1
readingssss
4
但是实际运行结果
很奇怪,更奇怪的是
如果把
printf("reading");
改成
printf("reading\n");
结果就会变成
最后发现是write/printf函数的问题
write函数没有缓冲区,printf函数有缓冲区.当使用write函数时,会直接打印到控制台,
printf只有当遇到"\n"时或者程序终止时才会将缓冲区里的字符串打印出来,也可以调用fflush(stdout)强制把缓冲区输出。
或者在处理i/o之前调用setvbuf函数如:
setcbuf(stdout,0,_IONBUF,0)//这样可以使得printf立即输出不占用缓冲区
printf("aaaa");
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。