I/O模型

1 、阻塞式IO模型

套接字的默认状态均为阻塞,产生阻塞的操作有下面四类

(1)读操作

read时对于一个阻塞套接字,如果该套接字的接收缓冲区没有数据可读,则该进程将被投入睡眠,直到有数据到达。对于非阻塞套接字如果接收缓冲区没有数据可读则调用会立即返回一个EWOULDBLOCK错误。

(2)写操作

write时对于一个阻塞套接字,如果该套接字的发送缓冲区没有空间,则该进程将被投入睡眠,直到有空间为止。对于非阻塞套接字如果发送缓冲区没有空间则调用会立即返回一个EWOULDBLOCK错误。如果有部分空间则返回值将是该缓冲区中的字节数。

(3)accept

对于一个阻塞套接字,accept函数被调用时在没有新的连接到达时进程会一直被投入睡眠。于非阻塞套接字调用会立即返回一个EWOULDBLOCK错误。

(4)connnect

阻塞套接字将会阻塞到三次握手的最后一个ACK,对于一个非阻塞套接字连接不能立即建立时会返回一个EINPROGRESS错误,表示连接建立已经启动但是尚未完成。

2 、非阻塞IO模型


3 、I/O复用模型
IO复用模型是多了一个select函数,select函数有一个参数是文件描述符集合,意思就是对这些的文件描述符进行循环监听,当某个文件描述符就绪的时候,就对这个文件描述符进行处理。

这种IO模型是属于阻塞的IO。但是由于它可以对多个文件描述符进行阻塞监听,所以它的效率比阻塞IO模型高效。

另外多路复用IO为何比非阻塞IO模型的效率高是因为在非阻塞IO中,不断地询问socket状态是通过用户线程去进行的,而在多路复用IO中,轮询每个socket状态是内核在进行的,这个效率要比用户线程要高的多。

int select (int maxfd + 1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval * timeout);
参数一:最大的文件描述符加1。
参数二:用于检查可读性,
参数三:用于检查可写性,
参数四:用于检查带外数据,
参数五:一个指向timeval结构的指针,用于决定select等待I/o的最长时间。如果为空将一直等待。
timeval结构的定义:
struct timeval{
long tv_sec; // seconds
long tv_usec; // microseconds
}
返回值: >0:就绪描述字的正数目-1:出错0 :超时

readset writeset exceptset指定我们要让内核测试读、写和异常条件的描述字。如果对某一个的条件不感兴趣,就可以把它设为NULL。如果三个指针都为NULL,我们就有了一个比sleep()函数更为精确的定时器(sleep()以毫秒为最小单位,这个以微秒为单位)。

每次select返回之后都要通过函数FD_ISSET对套接字进行测试来确认是否是本套接字可读可写或者异常,原因是由于select会对小于等于maxfd的所有套接字进行监听,函数返回仅表示有套接字已经准备好了但是具体是哪个套接字准备好了需要应用层自己判断,select会通过将对应的fd_set的标志位置1来告诉调用者哪个套接字准备好了,函数内部会先将fd_set清零、设置然后再返回。所以调用者可以在select返回之后通过调用FD_ISSET判断是哪个套接字准备好了,同时在下一次调用select之前需要重新调用FD_ZERO、FD_SET对需要监听的套接字进行设置。


4 、信号驱动IO模型
信号驱动IO模型是应用进程告诉内核:当你的数据报准备好的时候,给我发送一个信号哈,并且调用我的信号处理函数来获取数据报。这个模型是由信号进行驱动。


5 、异步IO模型
异步IO使用的不再是read和write的系统接口了,应用工程序调用aio_XXXX系列的内核接口。
当应用程序调用aio_read的时候,内核一方面去取数据报内容返回,另外一方面将程序控制权还给应用进程,应用进程继续处理其他事务。这样应用进程就是一种非阻塞的状态。

当内核的数据报就绪的时候,是由内核将数据报拷贝到应用进程中,返回给aio_read中定义好的函数处理程序。很少有linux系统支持,windows的IOCP则是此模型。


前面四种IO模型实际上都属于同步IO,只有最后一种是真正的异步IO,因为无论是多路复用IO还是信号驱动模型,IO操作的第2个阶段都会引起用户线程阻塞,也就是内核进行数据拷贝的过程都会让用户线程阻塞。

同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞!
阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值