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爬虫之抓取百度贴吧并存储到本地txt文件改进版
Nov 06 Python
Python模块、包(Package)概念与用法分析
May 31 Python
python安装gdal的两种方法
Oct 29 Python
Django实现CAS+OAuth2的方法示例
Oct 30 Python
浅谈Python类中的self到底是干啥的
Nov 11 Python
django数据模型(Model)的字段类型解析
Dec 25 Python
Python Numpy 控制台完全输出ndarray的实现
Feb 19 Python
Python GUI库PyQt5样式QSS子控件介绍
Feb 25 Python
python 插入日期数据到Oracle实例
Mar 02 Python
python 录制系统声音的示例
Dec 21 Python
Python读取pdf表格写入excel的方法
Jan 22 Python
python字符串的一些常见实用操作
Apr 06 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蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
PHP中redis的用法深入解析
2014/02/20 PHP
PHP中创建图像并绘制文字的例子
2014/11/19 PHP
php插入mysql数据返回id的方法
2018/05/31 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
基于node.js的快速开发透明代理
2010/12/25 Javascript
jQuery.Validate验证库的使用介绍
2013/04/26 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
2014/01/11 Javascript
jQuery动画与特效详解
2015/02/01 Javascript
JavaScript里实用的原生API汇总
2015/05/14 Javascript
对类Vue的MVVM前端库的实现代码
2018/09/07 Javascript
JS实现基本的网页计算器功能示例
2020/01/16 Javascript
python 随机数生成的代码的详细分析
2011/05/15 Python
Python中常用操作字符串的函数与方法总结
2016/02/04 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
python爬虫获取小区经纬度以及结构化地址
2018/12/30 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
python 实现简单的FTP程序
2019/12/27 Python
python邮件中附加文字、html、图片、附件实现方法
2021/01/04 Python
Python 中 sorted 如何自定义比较逻辑
2021/02/02 Python
利用Python实现最小二乘法与梯度下降算法
2021/02/21 Python
HTML5是否真的可以取代Flash
2010/02/10 HTML / CSS
荷兰超市:DEEN
2018/03/14 全球购物
Java方面的关于数组和继承的笔面试题
2015/09/18 面试题
描述内存分配方式以及它们的区别
2016/10/15 面试题
应届毕业生求职信范文
2014/05/08 职场文书
五好关工委申报材料
2014/05/31 职场文书
运动会方队口号
2014/06/07 职场文书
《中国梦我的梦》小学生演讲稿
2014/08/20 职场文书
2014年财务工作总结范文
2014/11/11 职场文书
2015年团支部工作总结
2015/04/03 职场文书
告诉你创业计划书的8个实用技巧
2019/07/12 职场文书
css position fixed 左右双定位的实现代码
2021/04/29 HTML / CSS
React配置子路由的实现
2021/06/03 Javascript
Python requests用法和django后台处理详解
2022/03/19 Python