非阻塞I/O
非阻塞I/O使我们可以调用open,read,write这样的I/O操作,并使这些操作不会永远阻塞。如果这种操作不能完成,则调用立即出错返回,表示该操作如继续执行将阻塞。
对于一个给定的描述符,有两种方法对其指定非阻塞I/O:
1 如果调用open获得描述符,则可指定O_NONBLOCK标志
2 对于一个已经打开的描述符,则可调用fcntl,由该函数打开O_NONBLOCK文件状态标志。
示例:设置标准输出的非阻塞特性
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
void set_fl(int fd,int flags);
void clr_fl(int fd,int flags);
char buf[500000];
/*设置非阻塞特性*/
void set_fl(int fd,int flags)
{
int val;
if((val=fcntl(fd,F_GETFL,0))<0)
printf("fcntl F_GETFL error/n");
val|=flags;
if((val=fcntl(fd,F_SETFL,0))<0)
printf("fcntl F_SETFL error/n");
}
/*取消非阻塞特性*/
void clr_fl(int fd,int flags)
{
int val;
if((val=fcntl(fd,F_GETFL,0))<0)
printf("fcntl F_GETFL error/n");
val&=~flags;
if((val=fcntl(fd,F_SETFL,0))<0)
printf("fcntl F_SETFL error/n");
}
int main(void)
{
int ntowrite,nwrite;
char *ptr;
/*从标准输入读取数据,对于终端,一次只读一行,以回车键为结束标志*/
ntowrite=read(STDIN_FILENO,buf,sizeof(buf));
fprintf(stderr,"read %d bytes/n",ntowrite);
/*设置STDOUT_FILENO的非阻塞特性*/
set_fl(STDOUT_FILENO,O_NONBLOCK);
ptr=buf;
while(ntowrite>0){
errno=0;
nwrite=write(STDOUT_FILENO,ptr,ntowrite);
fprintf(stderr,"nwrite=%d,erron=%d/n",nwrite,errno);
if(nwrite>0){
ptr+=nwrite;
ntowrite-=nwrite;
}
}
/*取消STDOUT_FILENO的非阻塞特性*/
clr_fl(STDOUT_FILENO,O_NONBLOCK);
exit(0);
}
笔记:
(1) STDIN_FILENO STDOUT_FILENO与STDIN STDOUT
stdin类型为 FILE* stdin等是FILE *类型,属于标准I/O,高级的输入输出函数。在 <stdio.h>。
STDIN_FILENO类型为 int
使用stdin的函数主要有:fread、fwrite、fclose等,基本上都以f开头
使用STDIN_FILENO的函数有:read、write、close等
STDIN_FILENO等是文件描述符,是非负整数,一般定义为0, 1, 2,属于没有buffer的I/O,直接调用系统调用,在 <unistd.h>中。
(2) read在终端读取只读一行,以回车结束。
(3) 用fcntl设置文件的非阻塞特性。
(4) 这里给出了一个可能会出现写中断情况的处理。