UNIX四种IO模型

四种IO模型
一、阻塞IO
效率低,当应用程序中同时处理多路输入输出流,就得不到预期的目的。当tcp的recv读数据为空时,会一直阻塞,返回值为读到的字节数。除非发送端关闭时,返回值为0,
二、非阻塞IO
当无数据是直接返回,同时置errno为EAGAIN,再试一次,可以在循环里面轮询,直至读到数据,缺点是占用cpu资源
阻塞可以通过打开文件时指定参数,也可以在打开后通过文件控制函数fcntl来设定,对于socket,只能通过后者


flag = fcntl(socketfd,F_GETFL,0)
flag |=O_NONBLACK(设置阻塞) 
flag &=~O_NONBLACK(设置非阻塞)
fcntl(socketfd,F_SETFL,flag)


三、多路复用
为解决上面两种模型的缺点,如果采用多进程,每个进程处理一路数据,将会产生进程间同步问题,使程序更加复杂。比较好的方法是:
先构造一张有关描述符的表fdset,只有当这些描述符里一个或多个就绪时才返回(由操作系统完成),进行IO。
fdset相当于int[32],1024位,和进程中打开文件的文件描述符编号一一对应,当需要检测某个fd有无数据时,就把对应位置1。
具体操作函数:
fd_set rdfs;定义一个表
int maxfd;
FD_ZERO(&rdfs)把表清零
FD_SET(0,&rdfs) FD_SET(listenfd,&rdfs)把要检测的流对应位置1
select(maxfd+1,(fd_set *),(fd_set *),(fd_set *),timeout)
第一个参数为文件描述符的最大值+1,每一个文件描述符对应于三个流,所以fd_set也对应于三种监控,有输入,有输出,有错误。对应的fd_set写在对应的位置上。
timeout:为NULL时,当监控的流都不满足时,阻塞,直至有流能满足
为timeval时,若设为0(不同于NULL)或大于0时,则立刻返回或超出timeval后返回有多少个流满足要求
多路复用可以同时处理多个数据流,且不用轮询,浪费cpu资源。当所有的流都不满足时,在select上睡眠。
四、信号驱动
1)这是一种异步通知模式
2)需要底层驱动的支持

你可能感兴趣的:(嵌入式)