https://www.cnblogs.com/wangjun187197/p/9642429.html

Python之路--协程/IO多路复用

I/O复用模型

此模型用到select和poll函数,这两个函数也会使进程阻塞,select先阻塞,有活动套接字才返回,但是和阻塞I/O不同的是,这两个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写(就是监听多个socket)。select被调用后,进程会被阻塞,内核监视所有select负责的socket,当有任何一个socket的数据准备好了,select就会返回套接字可读,我们就可以调用recvfrom处理数据。
正因为阻塞I/O只能阻塞一个I/O操作,而I/O复用模型能够阻塞多个I/O操作,所以才叫做多路复用。

引子:

  之前学习过了,线程,进程的概念,知道了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把CPU的利用率提高很多了.但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程,创建线程,以及管理他们之间的切换.

  随着我们对于效率的最求不断提高,基于单线程来实现并发又成为一个新的课题.即只用一个主线程的情况下实现并发.这样就可以节省创建线程进程所消耗的时间.

  并发的本质: 切换+保存状态

  cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是任务发生了阻塞,另外一种情况是该任务计算时间过长

  

  对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程。

  协成的本质就是在单线程下,由用户自己控制一个任务遇到IO阻塞就切换另一个任务去执行,一次来提升效率.

可以控制对个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行.

作为1的补充;可以检测IO操作,在遇到IO操作的情况下才发生切换

协程介绍:

协程:是单线程下的并发,又称为为线程. 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的.

协程特点:

  必须在只有一个单线程里实现并发

  修改共享数据不需加锁

  用户程序里自己保存多个控制流的上下文栈

  一个协程遇到IO操作自动切换到其他协程

Greenlet模块

安装:pip3 install greenlet

greenlet实现状态切换

Gevent模块

安装:pip3 install gevent

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet,它是以C扩展模块形式接入Python的轻量级线程.Greenlet全部运行在主程序操作系统进程的内部,但他们被协作式的调度.

遇到IO主动切换

IO多路复用

IO多路复用作用:检查多个socket是否已经发生变化(是否连接成功/是否已经获取数据)(可读/可写)

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。

三种模式:

  select:最多1024个socket;循环去检测。

  poll:不限制监听socket个数;循环去检测(水平触发)。

  epoll:不限制监听socket个数;回调方式(边缘触发)。

基于IO多路复用+socket实现并发请求:

IO多路复用

socket 非阻塞(不等待)

异步:执行完某个任务后自动调用我给它的函数

Python中开源 基于事件循环实现的异步非阻塞框架 Twisted

socket发生请求

单线程解决并发

解决并发,多线程

提高并发方案:

--多进程

--多线程

--异步非阻塞模块(Twisted) scrapy框架(单线程完成并发)

单线程完成并发

什么是异步非阻塞?

  --非阻塞:不等待

    比如创建socket对某个地址进行connect,获取接收数据recv时默认都会等待(连接成功或接收到数据),才执行后续操作.如果设置setblocking(False),以上两个过程就不在等待,到时会报BlockingIOError的错误,只要捕获即可.

  --异步,通知,执行完成后自动执行回调函数或自动执行某些操作(通知)

    比如做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自动执行回调函数.

什么是同步阻塞?

--阻塞:等

--同步:按照顺序逐步执行

key_list = ['alex','db','sb']

for item in key_list:

ret = requests.get('https://www.baidu.com/s?wd=%s' %item)

print(ret.text)

IO多路复用,协程的更多相关文章

  1. Python IO 多路复用 \协程

    IO 多路复用 作用:  检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据) 即(可读/可写) IO请求时 解决并发  :  单线程 def get_data(key): cl ...

  2. Python异步IO之协程(一):从yield from到async的使用

    引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中 ...

  3. 进程&线程(三):外部子进程subprocess、异步IO、协程、分布式进程

    1.外部子进程subprocess python之subprocess模块详解--小白博客 - 夜风2019 - 博客园 python subprocess模块 - lincappu - 博客园 之前 ...

  4. day41 - 异步IO、协程

    目录 (见右侧目录栏导航) - 1. 前言- 2. IO的五种模型- 3. 协程    - 3.1 协程的概念- 4. Gevent 模块    - 4.1 gevent 基本使用    - 4.2 ...

  5. 异步IO(协程,消息循环队列)

    同步是CPU自己主动查看IO操作是否完成,异步是IO操作完成后发出信号通知CPU(CPU是被通知的) 阻塞与非阻塞的区别在于发起IO操作之后,CPU是等待IO操作完成再进行下一步操作,还是不等待去做其 ...

  6. python---异步IO(asyncio)协程

    简单了解 在py3中内置了asyncio模块.其编程模型就是一个消息循环. 模块查看: from .base_events import * from .coroutines import * #协程 ...

  7. Python异步IO之协程(二):使用asyncio的不同方法实现协程

    引言:在上一章中我们介绍了从yield from的来源到async的使用,并在最后以asyncio.wait()方法实现协程,下面我们通过不同控制结构来实现协程,让我们一起来看看他们的不同作用吧- 在 ...

  8. python-gevent模块(自动切换io的协程)

    2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import gevent     def foo() ...

  9. 异步IO和协程

    1-1.并行:真的多任务执行(CPU核数>=任务数):即在某个时刻点上,有多个程序同时运行在多个CPU上 1-2.并发:假的多任务执行(CPU核数<任务数):即一段时间内,有多个程序在同一 ...

随机推荐

  1. [JZOJ5977] 【清华2019冬令营模拟12.15】堆

    题目 其中n,q≤500000n,q\leq 500000n,q≤500000 题目大意 让你维护一个堆.支持一下操作: 在某个点的下面加上另一个点,然后进行上浮操作. 询问某一点的权值. 思考历程 ...

  2. 日志服务与SIEM(如Splunk)集成方案实战

    背景信息 目标 本文主要介绍如何让阿里云日志服务与您的SIEM方案(如Splunk)对接, 以便确保阿里云上的所有法规.审计.与其他相关日志能够导入到您的安全运维中心(SOC)中. 名词解释 LOG( ...

  3. android Serializable 和 Parcelable 区别

      android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable. 一 序列化原因: 1.永久性保存对象,保存对象的字节序列到本地文件中:2.通过 ...

  4. Android之TableLayout表格布局

    1.相关属性 1.1.常用属性 android:collapseColumns 设置需要被隐藏的列的序列号 android:shrinkColumns 设置允许被收缩的列的序列号 android:st ...

  5. 09_springmvc异常处理

    一.异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生. 系统的dao ...

  6. nginx使用手册--nginx的命令行参数

    nginx的命令行参数 -? 或者 -h 打印命令行参数帮助信息 -c file 为 Nginx 指定一个配置文件,来代替缺省的. -t 不运行,而仅仅测试配置文件.nginx 将检查配置文件的语法的 ...

  7. 关于排序--sort()和qsort()使用

    一.sort()函数的使用 使用sort()函数的时候要加上头文件#include<algorithm>和using namespace std. 这个函数接收两个或者三个参数. 第一个参 ...

  8. [转]MEF程序设计指南

    <MEF程序设计指南>博文汇总 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OSGI 实现以Spring 等等.在 Microsoft 的平台上,.NET Fr ...

  9. C动态分配内存

    malloc分配内存时不初始化,calloc分配内存并进行初始化.

  10. JavaSE_01_Exception类

    1.1 异常概念 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象.Java ...