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构建Hopfield网络的教程
Apr 14 Python
在Django中使用Sitemap的方法讲解
Jul 22 Python
python 数据清洗之数据合并、转换、过滤、排序
Feb 12 Python
Python图片裁剪实例代码(如头像裁剪)
Jun 21 Python
Django forms组件的使用教程
Oct 08 Python
python2和python3的输入和输出区别介绍
Nov 20 Python
python操作日志的封装方法(两种方法)
May 23 Python
Python matplotlib学习笔记之坐标轴范围
Jun 28 Python
Python中list的交、并、差集获取方法示例
Aug 01 Python
Python获取时间戳代码实例
Sep 24 Python
使用python实现时间序列白噪声检验方式
Jun 03 Python
浅谈TensorFlow之稀疏张量表示
Jun 30 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
综合图片计数器
2006/10/09 PHP
php数组函数序列之array_splice() - 在数组任意位置插入元素
2011/11/07 PHP
PHP使用PHPMailer发送邮件的简单使用方法
2013/11/12 PHP
PHP对象递归引用造成内存泄漏分析
2014/08/28 PHP
利用PHP生成静态html页面的原理
2016/09/30 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
js数字输入框(包括最大值最小值限制和四舍五入)
2009/11/24 Javascript
javascript深入理解js闭包
2010/07/03 Javascript
javascript实现表单提交后,提交按钮不可用的方法
2015/04/18 Javascript
基于BootStrap实现局部刷新分页实例代码
2016/08/08 Javascript
ie下js不执行的几种可能
2017/02/28 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
在 Node.js 中使用原生 ES 模块方法解析
2017/09/19 Javascript
基于vue cli 通过命令行传参实现多环境配置
2018/07/12 Javascript
nodejs require js文件入口,在package.json中指定默认入口main方法
2018/10/10 NodeJs
详解如何用typescript开发koa2的二三事
2018/11/13 Javascript
vue基于viewer实现的图片查看器功能
2019/04/12 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
在Vue环境下利用worker运行interval计时器的步骤
2019/08/01 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
vue中进行微博分享的实例讲解
2019/10/14 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
python将类似json的数据存储到MySQL中的实例
2019/07/12 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
2020/02/28 Python
在python tkinter界面中添加按钮的实例
2020/03/04 Python
python 常见的反爬虫策略
2020/09/27 Python
python爬取招聘要求等信息实例
2020/11/20 Python
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
小米旗下精品生活电商平台:小米有品
2018/12/18 全球购物
诺思信科技(南京)有限公司.NET笔试题答案
2013/07/06 面试题
消防志愿者活动方案
2014/08/23 职场文书
计划生育工作总结2015
2015/04/03 职场文书
MySQL删除和插入数据很慢的问题解决
2021/06/03 MySQL
详解Java七大阻塞队列之SynchronousQueue
2021/09/04 Java/Android