Linux系统下几种I/O模型

Linux下一般有阻塞非阻塞I/O多路复用异步几种I/O模型。由于是初次接触,理解不是很到位,后面再进行完善。

      阻塞,Linux默认的Socket一般都是这种模式,一个process工作此模式下,内核只能一次只能处理一个I/O请求,阻塞应用程序其他的I/O请求,直到当前I/O所请求的数据完全得到后,从内核拷贝到用户进程,返回应用程序一个echo,解除阻塞状态,进行下一个I/O处理。

      非阻塞,和阻塞不同的一点是内核不会不响应来自应用程序的请求,应用程序每发起一个I/O请求,此时内核如果在处理另一个I/O,就会返回一个error给应用程序,告诉应用程序数据未准备好;如果此时内核处理完了上一个I/O请求,接下来响应当前的I/O请求不返回error,进行I/O处理。

       多路I/O复用,先构造一张有关描述符的列表,然后调用一个函数进行监控,直到这些描述符中的一个已经准备好进行I/O时,此监控函数返回,返回时候,告诉进程那个描述符已经准备好可以进行I/O。这种模式下的方式有poll、pselect、select与epoll。这里需要注意的一点是,在I/O请求特别多的情况下,select/epoll可以显示出其强大的能力,极大地减少系统的开销,提高系统的响应时间,而在I/O请求不是很多的情况下,采用多线程处理的模式会获得比多路I/O较好的效果,所以不能从处理单个请求快慢的角度来评价,从某种角度上说,select/epoll是可以处理大量的请求。

        异步I/O,进程发起一个I/O请求后,内核会立刻返回,进程不会阻塞,进程会继续进行下面的任务,内核完成数据的处理后,发送一个信号通知进程,从内核拷贝到用户进程,完成I/O的处理。这个异步I/O看似是所有I/O调用中最完美地,但是也存在问题:首先是不是所有系统都能很好地支持这种调用,system v提供一种信号SIGPOLL,但是只是当描述符引用STREAM设备的时候才会工作,BSD中提供一个信号SIGIO,只是当描述符引用终端设备或者网络的时候才会工作。其次,这种信号对于每个进程来书只有一个,如果要使信号对多个描述符都起作用,那么在接受到信号后无法判断哪个描述符可以进行I/O通讯,则仍然需要将这些描述符设置为非阻塞形式,进行轮询。

这里Mark一下编译异步I/O时候需要注意的一个小小的问题:

aio.c:(.text+0xd3): undefined reference to `aio_read'
/tmp/ccEkutyI.o: In function `on_input':
aio.c:(.text+0x16c): undefined reference to `aio_error'
aio.c:(.text+0x18a): undefined reference to `aio_return'

从上述错误可以看出,aio_read、aio_error、aio_return函数未定义,但是在aio.h中已有定义,这里在操作异步I/O的时候,编译程序需要添加-lrt项,如下所示:

gcc aio.c -lrt -lpthread -o aio_test

按照广义的分类,阻塞、非阻塞、多路复用这几种I/O都是同步I/O。所谓的同步I/O就是在数据处理的过程中会阻塞,而异步I/O完全不会阻塞,这几种I/O阻塞的情况如下:



 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值