一、阻塞IO
读阻塞:当用户读取数据时,没有资源,程序就会在当前位置阻塞
read、scanf、fgets、fgetc、recvfrom、accept...
写阻塞:当缓冲区满时,会出现写阻塞
write、puts
使用阻塞io有可能会阻碍程序的正常执行
二、非阻塞IO
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
功能:把文件描述符设置为非阻塞模式,调用阻塞IO就是非阻塞模式了
参数:
fd:指定文件的文件描述符
cmd:
F_GETFL:读取文件描述符属性
F_SETFL:设置文件描述符属性
arg:
cmd为F_GETFL,为0
cmd为F_SETFL,为 flag | O_NONBLOCK 的结果
将文件描述符的属性设置为非阻塞步骤:
1.先获取指定文件描述符的属性
int fd = open();
int flag=fcntl(fd,F_GETFL,0);
2.修改文件描述符属性为非阻塞
flag=flag | O_NONBLOCK;
3.将该属性添加到文件描述符中
fcntl(fd,F_SETFL,flag);
使用非阻塞IO,会频繁调用函数,如果函数没有资源,直接错误返回,所以会在调用函数时消耗大量系统资源
int main(int argc, char *argv[])
{
int fd = open("/dev/input/mice", O_RDONLY);
if(fd < 0)
{
perror("open");
exit(-1);
}
int flag = fcntl(0, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(0, F_SETFL, flag);
flag = fcntl(fd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(fd, F_SETFL, flag);
char buf[64] = {0};
char buf1[64] = {0};
while(1)
{
fgets(buf, 64, stdin);
printf("%s", buf);
read(fd, buf1, 64);
printf("%d -- %d -- %d\n", buf1[0], buf1[1], buf1[2]);
}
return 0;
}
三、IO多路复用
select
poll
epoll