非阻塞IO
- 如果内核还没有将数据准备好,系统调用会直接返回,并且返回EWOULDBLOCK错误码。
首先介绍一下函数fcntl
fcntl
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, .../*arg*/);
//传入的cmd不同,后面的参数不一样
fcntl有下面5种功能
- 复制⼀个现有的描述符(cmd=F_DUPFD).
- 获得/设置⽂件描述符标记(cmd=FGETFD或FSETFD).
- 获得/设置⽂件状态标记(cmd=FGETFL或FSETFL).
- 获得/设置异步I/O所有权(cmd=FGETOWN或FSETOWN) .
- 获得/设置记录锁(cmd=FGETLK,FSETLK或F_SETLKW ).
基于fcntl实现一个SetNoBlock,并轮询读取文件描述符。
void SetNoBlock(int fd)
{
int fl = fcntl(fd, F_GETFL);
if(fl < 0)
{
perror("fcntl");
return;
}
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}
//使⽤F_GETFL将当前的⽂件描述符的属性取出来(这是⼀个位图).
//然后再使⽤FSETFL将⽂件描述符设置回去. 设置回去的同时, 加上⼀个O_NONBLOCK参数
int main()
{
SetNoBlock(0);
while(1)
{
char buf[1024] = {0};
ssize_t size = read(0, buf, sizeof(buf)-1);
if(size < 0)
{
perror("read");
sleep(1);
continue;
}
printf("input:%s\n", buf);
}
return 0;
}