广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python之IO多路复用
  • 435
分享到

python之IO多路复用

多路复用python 2023-01-31 06:01:38 435人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

  同步io和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?  不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。  本文讨论的背景是linux环境下的network IO。  在进行解释之前,首先要说明几


  同步io和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?

  不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。

  本文讨论的背景是linux环境下的network IO。


  在进行解释之前,首先要说明几个概念:

  进程切换

  进程的阻塞

  文件描述符

  缓存 I/O


  进程切换

  为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。

  因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。


  从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:

  1. 保存处理器上下文,包括程序计数器和其他寄存器

  2. 更新PCB信息

  3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列

  4. 选择另一个进程执行,并更新其PCB

  5. 更新内存管理的数据结构

  6. 恢复处理器上下文


  进程控制块PCB(Processing Control Block),是操作系统核心中一种数据结构,主要表示进程状态。

  PCB的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位或与其它进程并发执行的进程。

  或者说,OS是根据PCB来对并发执行的进程进行控制和管理的。 

  PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息 


  进程的阻塞

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


  文件描述符fd

  文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。

  文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。

  当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

  在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

 

  缓存 I/O

  缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。

  在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中。

 数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。


  缓存 I/O 的缺点:

  数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。


  对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。

  一个IO(如read)操作会经历以下两个阶段:

  1. 等待数据准备 (Waiting for the data to be ready)

  2. 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)


  因为有了这两个阶段,linux系统产生了下面五种网络模式的方案。

  1.阻塞 I/O(blocking IO)

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

  3.I/O 多路复用( IO multiplexing)

  4.信号驱动 I/O( signal driven IO)

  5.异步 I/O(asynchronous IO)


  由于signal driven IO(信号驱动)在实际中并不常用,所以 里只提及剩下的四种IO Model。


  阻塞 I/O(blocking IO)

  在linux中,默认情况下所有的Socket都是blocking,一个典型的读操作流程大概是这样:

wKioL1iYT7vzXubWAAHfCAisEBU614.png

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


  所以,blocking IO的特点就是在IO执行的两个阶段都被block了。


  非阻塞 I/O(nonblocking IO)

  linux下,可通过设置socket使其变为非阻塞IO。当对一个non-blocking socket执行读操作时,流程是这个样子:

wKioL1iYUGXRiB3NAALWn86DDZs490.png

  当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。

  从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。


  所以,nonblocking IO的特点是用户进程需要不断的主动询问kernel数据好了没有。


 I/O 多路复用( IO multiplexing)

  IO multiplexing就是我们说的select,poll,epoll,有些地方也称这种IO方式为event driven IO。

  select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。

  它的基本原理就是select,poll,epoll这个function会不断的轮询所负责的所有socket

  当某个socket有数据到达了,就通知用户进程。

wKioL1iYUPSCZYvNAAKP56vk2aM729.png

  当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。


  所以,I/O 多路复用的特点是通过一种机制使一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。


  IO多路复用和阻塞IO其实并没有太大的不同,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而阻塞IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个连接。


  如果处理的连接数不是很高的话,使用select/epoll的WEB server不一定比使用多线程+阻塞IO的web server性能更好,可能延迟还更大。

  select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。


  在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking

  但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。


异步 I/O(asynchronous IO)

wKiom1iYUYGTEv9sAAJNKyciPpU590.png

  用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。

  然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。


  blocking和non-blocking的区别

    调用blocking IO会一直block住对应的进程直到操作完成

    调用non-blocking IO在kernel还准备数据的情况下会立刻返回

  synchronous IO和asynchronous IO的区别

   A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;

    An asynchronous I/O operation does not cause the requesting process to be blocked;

    两者的区别就在于synchronous IO做”IO operation”的时候会将process阻塞。

    之前所说的blocking IO,non-blocking IO,IO multiplexing都属于synchronous IO。

  

  有人会说,non-blocking IO并没有被block啊。 这里需要格外注意,定义中所指的”IO operation”是指真实的IO操作,就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候,如果kernel的数据没有准备好,这时候不会block进程。但是,当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。


  而asynchronous IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。


  各个IO Model的比较如图所示:

wKioL1iYUtPhxw8jAAKFlAzyOqM944.png

  通过上面的图片,可以发现non-blocking IO和asynchronous IO的区别还是很明显的。

  在non-blocking IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的check,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。

  而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。


I/O 多路复用之select、poll、epoll详解请往这走

--结束END--

本文标题: python之IO多路复用

本文链接: https://www.lsjlt.com/news/190707.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python之IO多路复用
      同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?  不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。  本文讨论的背景是Linux环境下的network IO。  在进行解释之前,首先要说明几...
    99+
    2023-01-31
    多路 复用 python
  • python IO多路复用之select
        说起IO操作我们最先想到的就是读写文件。其实python中对有三种IO操作,打开文件,使用socket进行网络连接和系统的标准输入输出sys.stdin和sys.stdout。我们先来看一段socket服务端的代码:import s...
    99+
    2023-01-31
    多路 复用 python
  • python IO多路复用之epoll详解
    什么是epoll epoll是什么?在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。当然...
    99+
    2022-11-11
  • IO多路复用丶基于IO多路复用+sock
      IO多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作   IO多路复用作用:     检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据...
    99+
    2023-01-30
    多路 复用 IO
  • Linux IO多路复用之epoll网络编程
    前言 本章节是用基本的linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下: 客户端从标准输入读入一行,发送到服务端 服务端从网络读取一行,然后输...
    99+
    2022-06-04
    linux epoll linux io多路复用 linux io多路复用之epoll网络编程
  • Redis的IO多路复用
    一、linux的IO复用函数同一个线程内,多个描述符的IO操作,能够并发交替地顺序执行。epoll只提供三个函数:int epoll_create(int size); #创建epoll句柄int epol...
    99+
    2022-10-18
  • Python之I/O多路复用
    回顾Socket一、Socket起源:socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些so...
    99+
    2023-01-31
    多路 复用 Python
  • PHP+Socket系列之IO多路复用及实现web服务器
    本篇文章给大家带来了关于php+socket的相关知识,其中主要介绍了IO多路复用,以及php+socket如何实现web服务器?感兴趣的朋友下面一起来看一下,希望对大家有帮助。php原生socket之IO多路复用以及实现web服务器多路复...
    99+
    2023-05-14
    php socket
  • IO多路复用原理(select、poll and epoll)
    IO多路复用首先要理解什么是多路?什么是复用? 多路:核心需求是要用尽可能少的线程来处理尽可能多的连接,这里的多路是指需要处理的众多连接。 复用:核心需求是要求使用尽可能少的线程,尽可能减少系统开销去处理尽可能多的连接,那么这个复用是指利用...
    99+
    2023-10-01
    服务器 linux
  • 如何从底层聊下IO多路复用模型
    本篇内容主要讲解“如何从底层聊下IO多路复用模型”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何从底层聊下IO多路复用模型”吧!前言当我们去面试的时候,问到了...
    99+
    2022-10-19
  • 详解IO多路复用机制——select、poll、epoll的原理和区别
    🌟 前言 🐶 大家好,我是周周,目前就职于国内短视频小厂BUG攻城狮一枚。 🤺 如果文章对你有帮助,记得关注、点赞、收藏,一键三连哦,你的支持将成为我最...
    99+
    2023-10-11
    linux 运维 服务器
  • python3--IO模型,阻塞,非阻塞,多路复用,异步,selectors模块
    协程回顾协程 实际上是一个线程执行了多个任务,遇到IO就切换示例:import time import gevent def func():     print('...
    99+
    2023-01-30
    多路 复用 模块
  • 怎么使用Python多路复用selector模块
    本篇内容主要讲解“怎么使用Python多路复用selector模块”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Python多路复用selector模块”吧!1. IO多路复用O多路复用...
    99+
    2023-06-25
  • python学习之路之案例3--多级菜单
    一、整个案例运用到的知识点   1.python数据结构之字典的使用,字典嵌套字典,字典嵌套列表   2.python数据结构之列表的使用,字典嵌套列表   3.python数据结构之字符串的使用,字符串的格式化   4.while Tru...
    99+
    2023-01-31
    之路 菜单 案例
  • BIO、NIO、IO多路复用模型详细介绍&Java NIO 网络编程
    文章目录 前言基本概念BIO过程NIO过程IO多路复用过程Java NIO编程Java NIO 核心概念Java NIO 示例 总结 前言 上文介绍了网络编程的基础知识,并基于 Jav...
    99+
    2023-08-30
    nio java 网络
  • Python多路复用selector模块的基本使用
    目录1. IO多路复用1.1. epoll,poll, select的比较2. selector模块的基本使用1. IO多路复用 O多路复用技术是使用一个可以同时监视多个IO阻塞的中...
    99+
    2022-11-12
  • BIO、NIO、IO多路复用模型详细介绍&Java NIO 网络编程
    文章目录 前言基本概念BIO过程NIO过程IO多路复用过程Java NIO编程Java NIO 核心概念Java NIO 示例 总结 前言 上文介绍了网络编程的基础知识,并基于 Java 编写了 BIO 的网络编程。我们知道...
    99+
    2023-08-16
    nio java 网络
  • 多路复用controlfile文件
    --在数据库开启的状态下做SQL>alter system set control_files='/u01/app/oracle/oradata/PROD4/PROD4/control01.ctl',...
    99+
    2022-10-18
  • PHP+Socket中IO多路复用及实现web服务器的方法是什么
    本篇内容介绍了“PHP+Socket中IO多路复用及实现web服务器的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php原生so...
    99+
    2023-07-05
  • 控制文件多路复用
    控制文件是oracle数据库中最重要的文件之一。它记录了数据库的名称及其他关键配置,也记录了当前数据库中所有的数据文件和日志文件的位置及状态等重要信息,是数据库启动过程中必须查找并且使用的关键文件。默认情况...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作