协程greenlet、gevent
greenlet
为了更好使用协程来完成多任务,python中greenlet模块对其封装,从而使得切换任务变得更加简单
安装方式
- pip3 install greenlet
示例代码:
- from greenlet import greenlet
- import time
- def test1():
- while True:
- print("-----真-----")
- gr2.switch()
- time.sleep(0.5)
- def test2():
- while True:
- print("-----真-----")
- gr1.switch()
- time.sleep(0.5)
- gr1 = greenlet(test1)
- gr2 = greenlet(test2)
- # 切换到gr1中运行
- gr1.swith()
gevent
greenlet已经实现了协程,但是这个工人切换,是不是觉得太麻烦了,不要着急,python还有一个比greenlet更强大的并且能够自动切换任务的模块`gevent`
其原理是当一个greentlet遇到IO(指的是input ouput输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO完成,再适当的时候切换回来继续执行。
由于IO操作非常耗时,经常使程序处于等待状态,有了gevent我们自动切换协程,就保证总有greenlet在运行,而不是等待IO
安装
- pip3 install gevent
1.gevent的使用
- import gevent
- def f(n):
- for i in range(n):
- print(gevent.getcurrent(), i)
- g1 = gevent.spawn(f, 5)
- g2 = gevent.spawn(f, 5)
- g3 = gevent.spawn(f, 5)
- g1.join()
- g2.join()
- g3.join()
运行结果
- F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
- <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 0
- <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 1
- <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 2
- <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 3
- <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 4
- <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 0
- <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 1
- <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 2
- <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 3
- <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 4
- <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 0
- <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 1
- <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 2
- <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 3
- <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 4
- Process finished with exit code 0
gevent切换执行
- import gevent
- def f(n):
- for i in range(n):
- print(gevent.getcurrent(), i)
- # 用来模拟一个耗时操作,注意不是time模块中的sleep
- gevent.sleep(1)
- g1 = gevent.spawn(f, 5)
- g2 = gevent.spawn(f, 5)
- g3 = gevent.spawn(f, 5)
- g1.join()
- g2.join()
- g3.join()
运行结果
- F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
- <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 0
- <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 0
- <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 0
- <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 1
- <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 1
- <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 1
- <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 2
- <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 2
- <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 2
- <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 3
- <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 3
- <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 3
- <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 4
- <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 4
- <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 4
- Process finished with exit code 0
3. 给程序打补丁
- from gevent import monkey
- import gevent
- import random
- import time
- # 有耗时操作时需要
- monkey.patch_all() # 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块
- def coroutine_work(coroutine_name):
- for i in range(10):
- print(coroutine_name, i)
- time.sleep(random.random())
- gevent.joinall([
- gevent.spawn(coroutine_work, "work1"),
- gevent.spawn(coroutine_work, "work2")
- ])
运行结果
- F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_test.py
- work1 0
- work2 0
- work2 1
- work1 1
- work1 2
- work1 3
- work2 2
- work1 4
- work1 5
- work2 3
- work1 6
- work1 7
- work2 4
- work2 5
- work1 8
- work1 9
- work2 6
- work2 7
- work2 8
- work2 9
- Process finished with exit code 0
协程greenlet、gevent的更多相关文章
- python 协程 greenlet gevent
一.并发的本质 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长时间片到了 二.协程 ...
- 线程队列 concurrent 协程 greenlet gevent
死锁问题 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...
- day 34 线程队列 线程池 协程 Greenlet \Gevent 模块
1 线程的其他方法 threading.current_thread().getName() 查询当前线程对象的名字 threading.current_thread().ident ...
- 协程,greenlet原生协程库, gevent库
协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...
- 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页
协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...
- 并发编程(六)——进程/线程池、协程、gevent第三方库
进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...
- python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)
1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...
- 协程----greenlet模块,gevent模块
1.协程初识,greenlet模块 2.gevent模块(需要pip安装) 一.协程初识,greenlet模块: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线 ...
- 14 并发编程-(协程)-greenlet模块&gevent模块
1.实现多个任务之间进行切换,yield.greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单 from greenlet import greenlet def eat(n ...
随机推荐
- 微信小程序登录逻辑
wx.getStorage({ key: 'session_id', success: function(res) { //如果本地缓存中有session_id,则说明用户登陆过 console.lo ...
- Docker查看运行中容器并进入容器
一.简述 Docker查看运行中容器并进入容器. 二.方法 $ sudo docker ps $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 将黄色文字替换 ...
- InfluxDB meta文件解析
操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 influxdb默认配置: /etc/influxdb/infl ...
- V-rep学习笔记:切削
V-REP allows you to perform cutting simulations. The user can model almost any type of cutting volum ...
- 单片机成长之路(51基础篇) - 012 MCS-51单片机控制详解–TMOD T2MOD
TMOD:工作方式控制寄存器 寄存器地址89H,不可位寻址. 位序 B7 B6 B5 B4 B3 B2 B1 B0 位符号 GATE C/T M1 M0 GATE C/T M1 M0 GATE——门控 ...
- 【C++】C++中类的基本使用
1.类和成员声明,定义,初始化的基本规则 C++中类的基本模板如下: namespace 空间命名{//可以定义namespace,也可以不定义 class/struct 类名称{ public/pr ...
- [转]ThreadLocal使用
引言 ThreadLocal的官方API解释为: “该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线 ...
- EPOLL AND Nonblocking I/O
https://medium.com/@copyconstruct/nonblocking-i-o-99948ad7c957 https://idndx.com/2014/09/02/the-impl ...
- 【iCore4 双核心板_ARM】例程二十六:LWIP_MODBUS_TCP实验——电源监控
实验现象: 核心代码: int main(void) { system_clock.initialize(); led.initialize(); adc.initialize(); delay.in ...
- Python threading 多参数传递方法
今天开启线程传递参数的时候,出现了一个小问题,一直不能传递多个参数,如下 import threading thread1 = threading.Thread(target=fun, args=[1 ...