阻塞IO / 非阻塞IO /IO多路复用 / 异步IO

说明:同步IO包含(阻塞IO / 非阻塞IO /IO多路复用),因为他们有个共同特性就是都需要内核态到用户态的一个等待。

基本概念解释,环境限定为linux:

1:用户空间和内存空间

首先操作系统是采用虚拟存储器,就32位系统来说,它的虚拟存储空间是2的32次方==4G,操作系统的核心是内核,它是独立于普通的应用程序,它可以访问受保护的内存空间,底层硬件等,为保障用户进程不能直接操作内核,操作系统将虚拟存储空间分为2部分,分为:内核空间和用户空间,内核空间将最高的1G字节(寻址:0xC0000000到0xFFFFFFFF)分配使用,最低的3G字节分配给用户空间,供进程使用。

2:进程切换

也就类似线程切换,由内核将正在CPU上执行的进程挂起,然后恢复以前挂起的进程,这就是进程切换。所以进程都是在操作系统的内核的支持下运行的。与内核紧密相连
从一个进程切换到另一个进程,运行过程如下:
1:保存处理机上下文,包括程序计数器和寄存器
2:更新PCB信息
3:把进程的PCB移入相应的队列,
4:选择另一个进程执行,并更新其PCB
5:更新内存管理的数据结构
6:恢复处理机上下文

3:进程的阻塞

当正在执行的进程运行期间,由于所期待的事情未发生,如(请求资源失败,某种操作的完成,新数据尚未到达等),则由系统自动执行阻塞原语,使进程自己由运行变为阻塞状态,由此可见,进程阻塞是进程自身的一种主动行为,因此只有运行的进程才能进入阻塞状态,处于阻塞状态的进程是不占用CPU资源的。

4:文件描述符

是一个用于表述指向文件的引用的抽象化概念。简单理解它就是一个索引值(非负整数),指向内核为每一个进程所维护的该进程打开的文件记录表

流程:程序打开一个文件或创建一个新文件,内核向进程返回一个文件描述符,通过文件描述符对文件句柄(就是真实文件对象)操作在程序设计底层基本是围绕文件描述符展开。这个概念只适用于unix,linux系统

5:缓存I/O

也被称为标准I/O,就是数据先被拷贝到操作系统的内核缓冲区,然后再从内核缓冲区拷贝到应用程序的地址空间。(就是说数据是从内核态到用户态的一个拷贝)
缺点:数据 在传输过程中需要在应用程序的地址空间和内核缓冲区中进行多次拷贝操作,这些拷贝操作对CPU和内存开销也是非常大。

I/O模式

I/O执行经历的2个阶段:
1:等待数据的准备,就是将数据先读到内核缓存中。
2:将数据从内核拷贝到进程中

通过这2个阶段,linux产生了5种网络模式:(阻塞I/0,非阻塞I/O,I/O多路复用,信号驱动I/O(这个用的少),异步I/O)

1:阻塞I/O (blocking IO)

在linux中,默认下所有的socket都是阻塞IO,
当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据(对于网络IO来说,很多时候数据在一开始还没有到达。比如,还没有收到一个完整的UDP包。
这个时候kernel就要等待足够的数据到来)。这个过程需要等待,也就是说数据被拷贝到操作系统内核的缓冲区中是需要一个过程的。而在用户进程这边,整个进程会被阻塞(当然,是进程自己选择的阻塞)。
当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
看图:

特点:blocking IO的特点就是在IO执行的两个阶段(内核等数据阶段和内核态到用户态考数据阶段)都被block了。

2:非阻塞I/O (nonblocking IO)

在linux中,可以设置socket为非阻塞IO,
当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。
看图:

特点:nonblocking IO的特点是用户进程需要不断的主动问kernel数据是否准备完毕。(这里数据从内核到用户还是存在阻塞)

3:IO多路复用 (IO multiplexing)
就是:select,poll,epoll,这3种方式也称作 事件驱动模型,selelct/epoll好处是单个process可以同时处理多个网络连接的IO,
基本原理:select,poll,epoll会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
看图:

注意:单线程下 阻塞模式是不能够实现多路复用
特点:I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。
当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。

4:异步IO (asynchronous IO) 实现全程无卡点

用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。
看图:

总结:
blocking和non-blocking的区别
调用blocking IO会一直block住对应的进程直到操作完成,而non-blocking IO在kernel还准备数据的情况下会立刻返回
synchronous IO和asynchronous IO的区别
synchronous IO做”IO operation”的时候会将process阻塞,所以(阻塞,非阻塞,多路复用)都属于同步IO

Python学习之-- IO 操作的更多相关文章

  1. [Python] Python 学习 - 可视化数据操作(一)

    Python 学习 - 可视化数据操作(一) GitHub:https://github.com/liqingwen2015/my_data_view 目录 折线图 散点图 随机漫步 骰子点数概率 文 ...

  2. python学习笔记:文件操作和集合(转)

    转自:http://www.nnzhp.cn/article/16/ 这篇博客来说一下python对文件的操作. 对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句 ...

  3. python学习之“切片操作从入门到精通”

    在python学习开发的过程中,我们总是不断的要对List(列表),Tuple(元组)有取值操作:假如我们有一个列表List1现在想取出1其中的前5个元素,改怎么操作呢? >>> L ...

  4. python中的IO操作

    python中的基本IO操作: 1) 键盘输入函数:raw_input(string),不作处理的显示,与返回. input(string),可以接受一个python表达式作为返回,python内部得 ...

  5. python学习笔记 IO 文件读写

    读写文件是最常见的IO操作.python内置了读写文件的函数. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统完成的,现代操作系统不允许普通的程序直接对磁盘进行操作,所以, 读写 ...

  6. python学习之IO:

    输入输出兼程IO操作,有同步(速度不匹配时四等)和异步(轮询和消息通知,复杂而高效) 一 文件操作函数: 文件打开:f=open("文件路径“,“操作类型 r/rb/w/a”,"编 ...

  7. [Python基础]006.IO操作

    IO操作 输入输出 print raw_input input 文件 打开文件 关闭文件 读文件 写文件 文件指针 实例 输入输出 输入输出方法都是Python的内建函数,并且不需要导入任何的包就可以 ...

  8. AI学习---数据IO操作&神经网络基础

    数据IO操作 TF支持3种文件读取:    1.直接把数据保存到变量中    2.占位符配合feed_dict使用    3. QueueRunner(TF中特有的) 文件读取流程 文件读取流程(多线 ...

  9. 5月2日 python学习总结 IO模型

    IO模型 1.阻塞IO 2.非阻塞IO 3.多路复用IO 4.异步IO 一.阻塞IO blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了. 实际上,除非 ...

随机推荐

  1. configure: error: MySQL library not found

    在CentOS系统中,安装zabbix进行configure时会遇到以下问题 ./configure --enable-server --enable-agent --with-mysql --wit ...

  2. java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()

    原因:hibernate-jpa-2.0-api-1.0.0.Final.jar.ejb3-persistence.jar中的javax.persistence与javaEE 5 Librares中的 ...

  3. sql 删除重复数据

    DELETE a FROM tbBuilding a WHERE EXISTS (SELECT 1 FROM tbBuilding b WHERE b.Province = a.Province AN ...

  4. upupw nginx服务器 rewrite设置

    最近开始尝试使用upupw的Nginx套件做开发,感觉还挺不错的,也遇到了一些问题,决定在这里记录一下,同时也希望可以帮助到一些人. 用习惯了Apache,改用Nginx之后会有些不适应,但是咬咬牙就 ...

  5. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'needDao' defined in URL

    这个是我修改过后的mapper,是我的mapper中的空间地址写错了呢

  6. VTK教程系列:VTK基础及应用开发教程

    由于OpenCV不能使用,只能使用VTK库的图像处理库,暂时还没有找到其他可以全面替代的库: CSDN东灵工作室:http://blog.csdn.net/www_doling_net/article ...

  7. 油猴和EX-百度脚本 百度网盘下载

    pansoso.com 搜网盘 油猴和EX-百度脚本.zip https://aleikeji.pipipan.com/fs/845023-331102839

  8. postman的关联,即如何在请求中引用上次请求返回的值

    做接口测试,一定会遇到这种情况,需要拿上次请求的值在本次请求中使用,比如,我们去测试一个东西,要去登录才能做其他的操作,需要拿到登录返回数据中的某些字段,比如,token啊等... 如果发一次请求,就 ...

  9. python基础一 day2

    内容:   3%%s   输出:3%s       后面的全部转义 结果: 如果是因为执行break语句导致循环提前结束,就不会执行else. 单位换算: 编码方式: ascii  unicode u ...

  10. 【转】Delphi 2010 Lite加装帮助文件

    基于爱好,下载了一个delphi 2010 lite,业余玩玩. 不过这东西是网友重新打包的,没有带帮助.在网上搜索一下加摸索后搞定.步骤如下: Delphi 2010本身的帮助(MSDN风格的)1. ...