关于epoll的IO模型是同步异步的一次纠结过程
《UNIX网络编程:卷一》第六章——I/O复用。书中向我们提及了5种类UNIX下可用的I/O模型:
阻塞式I/O;
非阻塞式I/O;
I/O复用(select,poll,epoll...);
信号驱动式I/O(SIGIO);
异步I/O(POSIX的aio_系列函数);
阻塞式I/O模型:默认情况下,所有套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操作通常包括两个不同阶段:
(1)等待数据准备好;
(2)从内核向进程复制数据。
对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所有等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。 好,下面我们以阻塞套接字的recvfrom的的调用图来说明阻塞
<img src="https://pic2.zhimg.com/50/e83d68da03da2e8c1568b4b4b630edfd_hd.jpg" data-rawwidth="1058" data-rawheight="556" class="origin_image zh-lightbox-thumb" width="1058" data-original="https://pic2.zhimg.com/e83d68da03da2e8c1568b4b4b630edfd_r.jpg">
标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。
非阻塞式I/O: 以下这句话很重要:进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把进程投入睡眠,而是返回一个错误。看看非阻塞的套接字的recvfrom操作如何进行
<img src="https://pic1.zhimg.com/50/4bc31cab27a9a732ab7d1ba9e674ed64_hd.jpg" data-rawwidth="1064" data-rawheight="631" class="origin_image zh-lightbox-thumb" width="1064" data-original="https://pic1.zhimg.com/4bc31cab27a9a732ab7d1ba9e674ed64_r.jpg">
可以看出recvfrom总是立即返回。
I/O多路复用:虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。如图
<img src="https://pic1.zhimg.com/50/b1ec6a4f16844a27c175d5a6a94cd7f8_hd.jpg" data-rawwidth="1136" data-rawheight="732" class="origin_image zh-lightbox-thumb" width="1136" data-original="https://pic1.zhimg.com/b1ec6a4f16844a27c175d5a6a94cd7f8_r.jpg">
信号驱动式I/O:用的很少,就不做讲解了。直接上图
<img src="https://pic1.zhimg.com/50/6294fb7f7f5c22e39187a490c35ac6f0_hd.jpg" data-rawwidth="1139" data-rawheight="711" class="origin_image zh-lightbox-thumb" width="1139" data-original="https://pic1.zhimg.com/6294fb7f7f5c22e39187a490c35ac6f0_r.jpg">
异步I/O:这类函数的工作机制是告知内核启动某个操作,并让内核在整个操作(包括将数据从内核拷贝到用户空间)完成后通知我们。如图:
<img src="https://pic2.zhimg.com/50/5819fd0fdff2bd4fdc9652291aca1831_hd.jpg" data-rawwidth="1109" data-rawheight="603" class="origin_image zh-lightbox-thumb" width="1109" data-original="https://pic2.zhimg.com/5819fd0fdff2bd4fdc9652291aca1831_r.jpg">
注意红线标记处说明在调用时就可以立马返回,等函数操作完成会通知我们。
等等,大家一定要问了,同步这个概念你怎么没涉及啊?别急,您先看总结。 其实前四种I/O模型都是同步I/O操作,他们的区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理。
<img src="https://pic4.zhimg.com/50/8244d924a12eaf42d61b41718c559bff_hd.jpg" data-rawwidth="3200" data-rawheight="1800" class="origin_image zh-lightbox-thumb" width="3200" data-original="https://pic4.zhimg.com/8244d924a12eaf42d61b41718c559bff_r.jpg">
再看POSIX对这两个术语的定义:
同步I/O操作:导致请求进程阻塞,直到I/O操作完成;
异步I/O操作:不导致请求进程阻塞。
好,下面我用我的语言来总结一下阻塞,非阻塞,同步,异步
阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待;
同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。
用 poll 时, poll通知用户空间的Appliation时, 数据还在内核空间, 所以Appliation调用 read API 时, 内部会做 copy socket data from kenel space to user space.
关于epoll的IO模型是同步异步的一次纠结过程的更多相关文章
- Linux的五种IO模型及同步和异步的区别
前置知识 缓存 I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O.在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
- Linux IO模型(同步异步阻塞非阻塞等)的几篇好文章
聊聊同步.异步.阻塞与非阻塞聊聊Linux 五种IO模型聊聊IO多路复用之select.poll.epoll详解
- IO模型:同步、异步、阻塞、非阻塞
前言: 在Linux的网络编程中,同步IO(synchronous IO).异步IO(asynchronous IO).阻塞IO(blocking IO).非阻塞IO(non-blocking IO) ...
- 5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
- IO模型分析
html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...
- 五种IO模型透彻分析
1.基础 在引入IO模型前,先对io等待时某一段数据的"经历"做一番解释.如图: 当某个程序或已存在的进程/线程(后文将不加区分的只认为是进程)需要某段数据时,它只能在用户空间中属 ...
- 并发编程——IO模型(6)
1.IO模型分类 同步IO #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义,其实绝大多数函数都是同步调用.但是一般而言,我们在说同步.异步的时候,特指那些需要 ...
随机推荐
- 如何插入sql数据
原:http://blog.csdn.net/Weicleer/article/details/47608289
- AtCoder square869120 Contest #3 F sushi
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- python 普通文件读写
with open('ttt.txt', 'w') as f: f.write('456.098909,9.090988,7.878765') with open('ttt.txt', 'r') as ...
- python datetime模块来获取当前的日期和时间
#!/usr/bin/python # -*- coding: UTF- -*- import datetime i = datetime.datetime.now() print ("当前 ...
- python 集合并集
#Union setx = set(["green", "blue"]) sety = set(["blue", "yellow& ...
- shell printf
printf 可以格式化字符串,还可以制定字符串的宽度.左右对齐方式等.默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n. 例子: $ echo "Hello, ...
- python - 面向对象编程(初级篇)
写了这么多python 代码,也常用的类和对象,这里准备系统的对python的面向对象编程做以下介绍. 面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) ...
- TestNG 101
最近看了点TestNG,做个入门笔记 0.Maven + TestNG 0a. 创建Maven 项目,pom中添加依赖(可能还需要安装TestNG插件 <dependencies> < ...
- 【异常】redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'PSETEX'
在spring中 针对 RedisTemplate类: private RedisTemplate<String, String> template; 当调用下面方法 template.o ...
- PHP导出为Word格式
<?php $file = './html.doc'; $table = '<table width="100%"><tr><td>'.i ...