python 协程 gevent原理与用法分析


Posted in Python onNovember 22, 2019

本文实例讲述了python 协程 gevent原理与用法。分享给大家供大家参考,具体如下:

gevent

greenlet已经实现了协程,但是这个还的人工切换,是不是觉得太麻烦了,不要捉急,python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent

其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的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()

运行结果

<Greenlet at 0x10e49f550: f(5)> 0
<Greenlet at 0x10e49f550: f(5)> 1
<Greenlet at 0x10e49f550: f(5)> 2
<Greenlet at 0x10e49f550: f(5)> 3
<Greenlet at 0x10e49f550: f(5)> 4
<Greenlet at 0x10e49f910: f(5)> 0
<Greenlet at 0x10e49f910: f(5)> 1
<Greenlet at 0x10e49f910: f(5)> 2
<Greenlet at 0x10e49f910: f(5)> 3
<Greenlet at 0x10e49f910: f(5)> 4
<Greenlet at 0x10e49f4b0: f(5)> 0
<Greenlet at 0x10e49f4b0: f(5)> 1
<Greenlet at 0x10e49f4b0: f(5)> 2
<Greenlet at 0x10e49f4b0: f(5)> 3
<Greenlet at 0x10e49f4b0: f(5)> 4

可以看到,3个greenlet是依次运行而不是交替运行

2. 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()

运行结果

<Greenlet at 0x7fa70ffa1c30: f(5)> 0
<Greenlet at 0x7fa70ffa1870: f(5)> 0
<Greenlet at 0x7fa70ffa1eb0: f(5)> 0
<Greenlet at 0x7fa70ffa1c30: f(5)> 1
<Greenlet at 0x7fa70ffa1870: f(5)> 1
<Greenlet at 0x7fa70ffa1eb0: f(5)> 1
<Greenlet at 0x7fa70ffa1c30: f(5)> 2
<Greenlet at 0x7fa70ffa1870: f(5)> 2
<Greenlet at 0x7fa70ffa1eb0: f(5)> 2
<Greenlet at 0x7fa70ffa1c30: f(5)> 3
<Greenlet at 0x7fa70ffa1870: f(5)> 3
<Greenlet at 0x7fa70ffa1eb0: f(5)> 3
<Greenlet at 0x7fa70ffa1c30: f(5)> 4
<Greenlet at 0x7fa70ffa1870: f(5)> 4
<Greenlet at 0x7fa70ffa1eb0: f(5)> 4

3. 给程序打补丁

from gevent import monkey
import gevent
import random
import time
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")
])

运行结果

work1 0
work1 1
work1 2
work1 3
work1 4
work1 5
work1 6
work1 7
work1 8
work1 9
work2 0
work2 1
work2 2
work2 3
work2 4
work2 5
work2 6
work2 7
work2 8
work2 9

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python中使用select模块实现非阻塞的IO
Feb 03 Python
python3 与python2 异常处理的区别与联系
Jun 19 Python
Python利用Beautiful Soup模块创建对象详解
Mar 27 Python
利用numpy和pandas处理csv文件中的时间方法
Apr 19 Python
django请求返回不同的类型图片json,xml,html的实例
May 22 Python
Python实现字典(dict)的迭代操作示例
Jun 05 Python
Python开发之Nginx+uWSGI+virtualenv多项目部署教程
May 13 Python
python 自动轨迹绘制的实例代码
Jul 05 Python
解决Numpy中sum函数求和结果维度的问题
Dec 06 Python
使用jupyter Nodebook查看函数或方法的参数以及使用情况
Apr 14 Python
Pytorch损失函数nn.NLLLoss2d()用法说明
Jul 07 Python
Python基于内置函数type创建新类型
Oct 22 Python
python 并发下载器实现方法示例
Nov 22 #Python
使用python绘制二维图形示例
Nov 22 #Python
python将邻接矩阵输出成图的实现
Nov 21 #Python
python实现小世界网络生成
Nov 21 #Python
使用Python的networkx绘制精美网络图教程
Nov 21 #Python
利用Python绘制Jazz网络图的例子
Nov 21 #Python
Python TCP通信客户端服务端代码实例
Nov 21 #Python
You might like
PHP+Javascript实现在线拍照功能实例
2015/07/18 PHP
PHP中使用foreach()遍历二维数组的简单实例
2016/06/13 PHP
PHP实现的敏感词过滤方法示例
2019/03/06 PHP
extjs grid取到数据而不显示的解决
2008/12/29 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
2013/07/17 Javascript
js中document.write使用过程中的一点疑问解答
2014/03/20 Javascript
深入学习JavaScript中的原型prototype
2015/08/13 Javascript
基于javascript实现句子翻牌网页版小游戏
2016/03/23 Javascript
vue2.0开发实践总结之入门篇
2016/12/06 Javascript
设置jquery UI 控件的大小方法
2016/12/12 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
详解angularjs中如何实现控制器和指令之间交互
2017/05/31 Javascript
JS使用tofixed与round处理数据四舍五入的区别
2017/10/25 Javascript
Vue拖拽组件开发实例详解
2018/05/11 Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
2018/09/14 Javascript
在微信小程序中使用mqtt服务的方法
2019/12/13 Javascript
JavaScript回调函数callback用法解析
2020/01/14 Javascript
JavaScript设计模式之观察者模式与发布订阅模式详解
2020/05/07 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
Python映射拆分操作符用法实例
2015/05/19 Python
python3+dlib实现人脸识别和情绪分析
2018/04/21 Python
Python快速查找list中相同部分的方法
2018/06/27 Python
Python类和对象的定义与实际应用案例分析
2018/12/27 Python
python3实现将json对象存入Redis以及数据的导入导出
2020/07/16 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
CSS3属性background-size使用指南
2014/12/09 HTML / CSS
Hunkemöller西班牙:欧洲最大的内衣连锁店
2018/08/15 全球购物
个人思想理论学习的自我鉴定
2013/11/30 职场文书
区三好学生主要事迹
2014/01/30 职场文书
广告学专业自荐信范文
2014/02/24 职场文书
项目经理聘任书
2014/03/29 职场文书
我的教育故事演讲稿
2014/05/04 职场文书
2014年人大工作总结
2014/12/10 职场文书
护理自荐信
2019/05/14 职场文书
Redis IP地址的绑定的实现
2021/05/08 Redis
MySql数据库 查询时间序列间隔
2022/05/11 MySQL