操作系统- Linux五种IO模型
-
1.阻塞IO模型
-
2.非阻塞IO模型
-
3.IO多路复用模型
-
4.信号驱动IO
-
5.异步IO模型
1.阻塞IO
IO一共分为两个阶段,第一个阶段是磁盘到内核空间,第二阶段是内核空间拷贝到用户空间。
当用户进程发起系统调用时,等待系统准备数据,然后系统准备好数据拷贝到用户空间,两个阶段都是阻塞的。
2.非阻塞IO
非阻塞IO发起系统调用后不会进入阻塞,而且在一个循环中不断询问系统是否准备好。但是拷贝数据到用户空间这个阶段是阻塞的。
3. IO多路复用
IO多路复用允许我们同时检查多个文件描述符,看其中任意一个是否可执行IO操作。
我们可以采用两个功能几乎相同的系统调用来执行IO多路复用操作
-
第一个是:
select()
-
第二个是:
poll()
文件描述符:是个很小的正整数,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。
3.1 select()系统调用
系统调用select()会一直阻塞,直到一个或多个文件描述符集合成为就绪态。
select()返回值
-
返回-1表示有错误发生
-
返回0表示在任何文件描述符成为就绪态之前select()调用已经超时。在这种勤快下,
每个返回的文件描述符集合都将被清空。 -
返回一个正整数表示一个或多个文件描述符已经达到就绪态。返回值表示处于就绪态的文件描述符的个数。
3.2 poll()系统调用
poll()与select()非常相似,本质上的区别就是存放 fd 集合的数据结构不一样。select 在一个进程内可以维持最多 1024 个连接,poll 在此基础上做了加强,可以维持任意数量的连接。
poll()的返回值
-
返回-1表示有错误发生
-
返回0表示该调用在任意一个文件描述符成为就绪态之前就超时了。
-
返回正整数表示有一个或多个文件描述符处于就绪态了。
文件描述符何时就绪:如果IO函数的调用不会阻塞,而不论该函数是否能够实际传输数据,该描述符被认为是就绪的
4.信号驱动IO
在信号驱动IO中,当文件描述符上可执行IO操作是,进程请求内核为自己发送一个信号,之后进程就可执行仍和其他的任务知道IO就绪位置,此时内核会发送信号给进程。也就是说,进程发起系统调用后,便可以做自己的事情,然后系统将数据拷贝到用户空间后便发送信号给进程。但是从内核空间拷贝到用户空间这个过程是阻塞的
4.1 epoll()系统调用
epoll()是基于事件驱动的I/O方式,是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。
4.2 select,poll,epoll比较
5.异步IO
当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作
6.五种IO模型比较
参考资料
《LINUX.UNIX系统编程手册(下册)》
https://www.cnblogs.com/chaser24/p/6112071.html