几种实现并发的手段

进程 
   启动多个进程 进程之间是由操作系统负责调用
线程
   启动多个线程 真正被CPU执行的最小单位实际是线程
开启一个线程 创建一个线程 寄存器 堆栈
关闭一个线程
协程
本质上是一个线程
能够在多个任务之间切换来节省一些IO时间
协程中任务之间的切换也消耗时间,但是开销要远远小于进程线程之间的切换

通过生成器来实现的协程

import time
def consumer():
while True:
x = yield
time.sleep(1)
print('处理了数据 :',x) def producer():
  # 创建一个生成器对象
c = consumer()
  # 激活这个生成器
next(c)
for i in range(10):
time.sleep(1)
print('生产了数据 :',i)
c.send(i) producer()

通过greenlet模块实现的协程

真正的协程模块就是使用greenlet完成的切换
from greenlet import greenlet
def eat():
print('eating start')
g2.switch()
print('eating end')
g2.switch() def play():
print('playing start')
g1.switch()
print('playing end')
g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch()

通过genevt模块实现的协程

可以看出来,greenlet只能实现两个代码之间的切换,但是我们使用协程的主要原因是在IO请求时,达到非阻塞的作用,所以我们需要使用gevent模块来让代码可以遇到阻塞就自由的切换

from gevent import monkey;monkey.patch_all()
import time
import gevent
import threading
def eat():
print(threading.current_thread().getName())
print(threading.current_thread())
print('eating start')
time.sleep(1)
print('eating end') def play():
print(threading.current_thread().getName())
print(threading.current_thread())
print('playing start')
time.sleep(1)
print('playing end') g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()
g2.join()

同步和异步的性能比较

进程和线程的任务切换由操作系统完成
协程任务之间的切换由程序(代码)完成,只有遇到协程模块能识别的IO操作的时候,程序才会进行任务切换,实现并发的效果 同步 和 异步
from gevent import monkey;monkey.patch_all()
import time
import gevent def task(n):
time.sleep(1)
print(n) def sync():
for i in range(10):
task(i) def async():
g_lst = []
for i in range(10):
g = gevent.spawn(task,i)
g_lst.append(g)
gevent.joinall(g_lst) # for g in g_lst:g.join() sync()
async()

什么时候可以使用协程??

在高IO的时候可以使用 例如爬虫, 爬虫需要请求很多url,使用协程可以让请求同时发出,而不会因为在等待一个url的请求响应而阻塞程序

不适用于高计算的环境, 因为在计算时cpu是一直工作的, 频繁的切换运行的程序,会白白增加切换程序的时间,导致计算效率下降


												

python中实现并发的手段之 协程的更多相关文章

  1. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

  2. Python 中的进程、线程、协程、同步、异步、回调

    进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...

  3. python中多线程,多进程,多协程概念及编程上的应用

    1, 多线程 线程是进程的一个实体,是CPU进行调度的最小单位,他是比进程更小能独立运行的基本单位. 线程基本不拥有系统资源,只占用一点运行中的资源(如程序计数器,一组寄存器和栈),但是它可以与同属于 ...

  4. Python中的多进程、多线程和协程

    本文中的内容来自我的笔记.撰写过程中参考了胡俊峰老师<Python程序设计与数据科学导论>课程的内容. 并发处理:多进程和多线程 前置 概念: 并发:一段时间内同时推进多个任务,但不一定要 ...

  5. Python、进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  6. Python并发编程系列之协程

    1 引言 协程是近几年并发编程的一个热门话题,与Python多进程.多线程相比,协程在很多方面优势明显.本文从协程的定义和意义出发,结合asyncio模块详细讲述协程的使用. 2 协程的意义 2.1 ...

  7. python并发编程之gevent协程(四)

    协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...

  8. python并发编程之asyncio协程(三)

    协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...

  9. Python中的并发

    目录 Python并发 并发三种层次 协程 生成者消费者 新关键字 网络io 线/进程 例子 线程池 进程通信 并发池 future对象 executor对象 参考 Python并发 并发三种层次 个 ...

随机推荐

  1. npm更新指定的组件

    1.例如:react-router已经更新到4.x版本,想要下载2.x版本,可以通过下面命令 npm install --save-dev react-router@2.8.1 或 npm insta ...

  2. 7.0-uC/OS-III中断管理

    1.CPU的中断处理 理器通常有多个中断源. 例如, UART中断. DMA中断. ADC中断.定时器中断等. 2.中断器件标志中断处理器,然后中断处理器将优先级最高的中断提交给CPU. 现在的中断控 ...

  3. python练习题-day13

    1.获取移动平均值 def wrapper(fun): def inner(*args,**kwargs): ret=fun(*args,**kwargs) ret.__next__() return ...

  4. 2019.04.13 python基础

    第一节    主要讲python背景  没什么要注意的  了解记住概念就好 python官网  python.org  自带shell  可以运行python代码 在IDLE中怎么运行代码 新建文本  ...

  5. JavaBean-EL-JSTL-MVC

    JavaBean规范 类必须使用public修饰     必须保证有公共无参数构造器.  (一般就是可以通过反射轻松的创建对象)  包含了属性的操作(给属性赋值,获取属性值). JavaBean中的成 ...

  6. vue-amap | 基于 Vue 2.x 与高德的地图组件

    vue-amap | 基于 Vue 2.x 与高德的地图组件 参考:https://elemefe.github.io/vue-amap/#/

  7. HBase笔记5(诊断)

    阻塞急救: RegionServer内存设置太小: 解决方案: 设置Region Server的内存要在conf/hbase-env.sh中添加export HBASE_REGIONSERVER_OP ...

  8. python_函数式编程

    函数式编程是一种编程范式 (而面向过程编程和面向对象编程也都是编程范式).在面向过程编程中,我们见到过函数(function):在面向对象编程中,我们见过对象(object).函数和对象的根本目的是以 ...

  9. log4j:WARN No appenders could be found for logger 解决方案

    我们在使用Log4j的时候,总是出现: log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.Log ...

  10. 《CSS世界》读书笔记(十)

    <!-- <CSS世界>张鑫旭著 --> 温和的padding属性 因为默认的box-sizing是content-box,所以使用padding会增加元素的尺寸. 尺寸表现对 ...