IO模型
阻塞I/O:最常用、最简单、效率最低
非阻塞I/O:可防止进程阻塞在I/O操作上,需要轮询
I/O 多路复用:允许同时对多个I/O进行控制
信号驱动I/O:一种异步通信模型
非阻塞I/O:
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
功能:
实现非阻塞
参数:
fd:文件描述符
cmd:设置的命令
F_GETFL
F_SETFL
arg:可有可无 由第二个参数决定
返回值:
文件状态标志
-1 :失败
int flag;
flag = fcntl(sockfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flag);
可以用fcntl改变文件状态标志,改变文件为非阻塞状态。
1、获取文件的flags,即open函数的第二个参数:
flags = fcntl(fd,F_GETFL,0);
2、设置文件的flags:
fcntl(fd,F_SETFL,flags);
3、增加文件的某个flags,比如文件是阻塞的,想设置成非阻塞:
flags = fcntl(fd,F_GETFL,0);
flags |= O_NONBLOCK;
fcntl(fd,F_SETFL,flags);
4、取消文件的某个flags,比如文件是非阻塞的,想设置成为阻塞:
flags = fcntl(fd,F_GETFL,0);
flags &= ~O_NONBLOCK;
fcntl(fd,F_SETFL,flags);
测试代码
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define N 128
int main(int argc, const char *argv[])
{
char buf[N] = { 0 };
int flags;
if((flags = fcntl(0, F_GETFL)) < 0)
{
perror("fail to fcntl");
return -1;
}
printf("flags = %#o\n", flags);
flags = flags | O_NONBLOCK;
printf("flags = %#o\n", flags);
if(fcntl(0, F_SETFL, flags) < 0)
{
perror("fail to fcntl");
return -1;
}
while(1)
{
sleep(3);
fgets(buf, N, stdin);
printf("buf = %s\n", buf);
sleep(1);
printf("*****************\n");
}
return 0;
}
测试结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2eb175909d6cfd057366175045e0b04f.png)