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基础教程之popen函数操作其它程序的输入和输出示例
Feb 10 Python
Python实现的最近最少使用算法
Jul 10 Python
Python正则表达式完全指南
May 25 Python
浅谈pycharm下找不到sqlalchemy的问题
Dec 03 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
Jan 15 Python
python处理自动化任务之同时批量修改word里面的内容的方法
Aug 23 Python
python3+opencv生成不规则黑白mask实例
Feb 19 Python
Django数据库操作之save与update的使用
Apr 01 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
Jun 08 Python
Keras 中Leaky ReLU等高级激活函数的用法
Jul 05 Python
python pygame 开发五子棋双人对弈
May 02 Python
python中 Flask Web 表单的使用方法
May 20 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文件锁函数flock()详细介绍
2014/11/18 PHP
详解WordPress开发中过滤属性以及Sql语句的函数使用
2015/12/25 PHP
简单谈谈PHP中strlen 函数
2016/02/27 PHP
在网页中控制wmplayer播放器
2006/07/01 Javascript
一段多浏览器的&quot;复制到剪贴板&quot;javascript代码
2007/03/27 Javascript
JavaScript 入门·JavaScript 具有全范围的运算符
2007/10/01 Javascript
javascript中万恶的function实例分析
2011/05/25 Javascript
JavaScript下通过的XMLHttpRequest发送请求的代码
2011/06/28 Javascript
JavaScript中Math对象方法使用概述
2014/01/02 Javascript
jQuery 和 CSS 的文本特效插件集锦
2014/12/12 Javascript
学习Javascript闭包(Closure)知识
2016/08/07 Javascript
浅析bootstrap原理及优缺点
2017/03/19 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
2019/09/11 Javascript
微信小程序登陆注册功能的实现代码
2019/12/10 Javascript
小程序如何写动态标签的实现方法
2020/02/05 Javascript
详解webpack-dev-middleware 源码解读
2020/03/23 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
linux服务器快速卸载安装node环境(简单上手)
2021/02/22 Javascript
python检测远程端口是否打开的方法
2015/03/14 Python
插入排序_Python与PHP的实现版(推荐)
2017/05/11 Python
Python 高级专用类方法的实例详解
2017/09/11 Python
使用matplotlib画散点图的方法
2018/05/25 Python
Python面向对象程序设计类的封装与继承用法示例
2019/04/12 Python
python 使用socket传输图片视频等文件的实现方式
2019/08/07 Python
jupyter note 实现将数据保存为word
2020/04/14 Python
如何配置关联Python 解释器 Anaconda的教程(图解)
2020/04/30 Python
在django admin中配置搜索域是一个外键时的处理方法
2020/05/20 Python
使用python把xmind转换成excel测试用例的实现代码
2020/10/12 Python
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
世界知名接发和假发品牌:Poze Hair
2017/03/08 全球购物
合作协议书模板2014
2014/09/26 职场文书
支行行长岗位职责
2015/02/15 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书
redis cluster支持pipeline的实现思路
2021/06/23 Redis
MySQL图形化管理工具Navicat安装步骤
2021/12/04 MySQL