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批量修改word文件名的方法示例
Oct 17 Python
python中yaml配置文件模块的使用详解
Apr 27 Python
解决Python网页爬虫之中文乱码问题
May 11 Python
Python3.4 tkinter,PIL图片转换
Jun 21 Python
python同时替换多个字符串方法示例
Sep 17 Python
Python通过Manager方式实现多个无关联进程共享数据的实现
Nov 07 Python
使用Python实现分别输出每个数组
Dec 06 Python
Python猜数字算法题详解
Mar 01 Python
Python列表切片常用操作实例解析
Mar 10 Python
如何解决pycharm调试报错的问题
Aug 06 Python
Python ellipsis 的用法详解
Nov 20 Python
python 模拟登陆163邮箱
Dec 15 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的ASCII码转换类
2013/07/05 PHP
PHP封装CURL扩展类实例
2015/07/28 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
PHP数组中头部和尾部添加元素的方法(array_unshift,array_push)
2017/04/10 PHP
JavaScript在IE和Firefox(火狐)的不兼容问题解决方法小结
2010/04/13 Javascript
firebug的一个有趣现象介绍
2011/11/30 Javascript
IE的有条件注释判定IE版本详解(附实例代码)
2012/01/04 Javascript
使用jQuery实现的网页版的个人简历(可换肤)
2013/04/19 Javascript
jQuery基于cookie实现的购物车实例分析
2015/12/24 Javascript
jQuery实现验证年龄简单思路
2016/02/24 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
2016/06/25 Javascript
第一次接触神奇的Bootstrap导航条
2016/08/09 Javascript
d3.js实现简单的网络拓扑图实例代码
2016/11/06 Javascript
JavaScript中定时控制Throttle、Debounce和Immediate详解
2016/11/17 Javascript
Vue 2.x教程之基础API
2017/03/06 Javascript
纯js封装的ajax功能函数与用法示例
2018/05/14 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
2018/09/08 Javascript
小程序扫描普通链接二维码跳转小程序指定界面方法
2019/05/07 Javascript
jquery实现聊天机器人
2020/02/08 jQuery
开发Node CLI构建微信小程序脚手架的示例
2020/03/27 Javascript
[56:24]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第二局
2016/03/04 DOTA
python安装oracle扩展及数据库连接方法
2017/02/21 Python
python matplotlib 在指定的两个点之间连线方法
2018/05/25 Python
tensorflow estimator 使用hook实现finetune方式
2020/01/21 Python
amazeui模态框弹出后立马消失并刷新页面
2020/08/19 HTML / CSS
Bluebella美国官网:英国性感内衣品牌
2018/10/04 全球购物
Linux如何命名文件--使用文件名时应注意
2012/01/22 面试题
中医专业应届生求职信
2013/11/17 职场文书
铁路工务反思材料
2014/02/07 职场文书
2014年社区学雷锋活动总结
2014/03/09 职场文书
廉洁校园实施方案
2014/05/25 职场文书
应聘会计求职信
2014/06/11 职场文书
2019年个人工作总结范文
2019/03/25 职场文书
导游词之镇江-金山寺
2019/10/14 职场文书
Python使用Kubernetes API访问集群
2021/05/30 Python