gevent介绍(转)
原文:https://www.liaoxuefeng.com/wiki/897692888725344/966405998508320
Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:
from gevent import monkey; monkey.patch_socket()
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()>
<Greenlet at 0x10e49f550: f()>
<Greenlet at 0x10e49f550: f()>
<Greenlet at 0x10e49f550: f()>
<Greenlet at 0x10e49f550: f()>
<Greenlet at 0x10e49f910: f()>
<Greenlet at 0x10e49f910: f()>
<Greenlet at 0x10e49f910: f()>
<Greenlet at 0x10e49f910: f()>
<Greenlet at 0x10e49f910: f()>
<Greenlet at 0x10e49f4b0: f()>
<Greenlet at 0x10e49f4b0: f()>
<Greenlet at 0x10e49f4b0: f()>
<Greenlet at 0x10e49f4b0: f()>
<Greenlet at 0x10e49f4b0: f()>
可以看到,3个greenlet是依次运行而不是交替运行。
要让greenlet交替运行,可以通过gevent.sleep()交出控制权:
def f(n):
for i in range(n):
print gevent.getcurrent(), i
gevent.sleep(0)
执行结果:
<Greenlet at 0x10cd58550: f()>
<Greenlet at 0x10cd58910: f()>
<Greenlet at 0x10cd584b0: f()>
<Greenlet at 0x10cd58550: f()>
<Greenlet at 0x10cd584b0: f()>
<Greenlet at 0x10cd58910: f()>
<Greenlet at 0x10cd58550: f()>
<Greenlet at 0x10cd58910: f()>
<Greenlet at 0x10cd584b0: f()>
<Greenlet at 0x10cd58550: f()>
<Greenlet at 0x10cd584b0: f()>
<Greenlet at 0x10cd58910: f()>
<Greenlet at 0x10cd58550: f()>
<Greenlet at 0x10cd58910: f()>
<Greenlet at 0x10cd584b0: f()>
3个greenlet交替运行,
把循环次数改为500000,让它们的运行时间长一点,然后在操作系统的进程管理器中看,线程数只有1个。
当然,实际代码里,我们不会用gevent.sleep()去切换协程,而是在执行到IO操作时,gevent自动切换,代码如下:
from gevent import monkey; monkey.patch_all()
import gevent
import urllib2 def f(url):
print('GET: %s' % url)
resp = urllib2.urlopen(url)
data = resp.read()
print('%d bytes received from %s.' % (len(data), url)) gevent.joinall([
gevent.spawn(f, 'https://www.python.org/'),
gevent.spawn(f, 'https://www.yahoo.com/'),
gevent.spawn(f, 'https://github.com/'),
])
运行结果:
GET: https://www.python.org/
GET: https://www.yahoo.com/
GET: https://github.com/
bytes received from https://www.python.org/.
bytes received from https://github.com/.
bytes received from https://www.yahoo.com/.
从结果看,3个网络操作是并发执行的,而且结束顺序不同,但只有一个线程。
小结
使用gevent,可以获得极高的并发性能,但gevent只能在Unix/Linux下运行,在Windows下不保证正常安装和运行。
由于gevent是基于IO切换的协程,所以最神奇的是,我们编写的Web App代码,不需要引入gevent的包,也不需要改任何代码,仅仅在部署的时候,用一个支持gevent的WSGI服务器,立刻就获得了数倍的性能提升。具体部署方式可以参考后续“实战”-“部署Web App”一节。
gevent介绍(转)的更多相关文章
- {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二
python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...
- 网络编程基础--协程--greenlet切换---gevent自动识别 IO ---
协程: 1 单线程来实现并发---协程: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 只 ...
- Gevent简明教程
Gevent简明教程 发表于 2015-11-28 | 分类于 技术| | 阅读次数 5159 前述 进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程.多线程.协程和异步. 多 ...
- Gevent高并发网络库精解
进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程.多线程.协程和异步. 多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库 多线程 ...
- python并开发编程之协程
一 引出协成 并发的本质是:切换+保存状态 CPU在运行行一个任务时,会在两种情况下切走去执行其他任务,一是该任务发生了阻塞,二是运行该任务的时间过长 yeild可以保存状态,yeild状态保存与操作 ...
- python开发concurent.furtrue模块:concurent.furtrue的多进程与多线程&协程
一,concurent.furtrue进程池和线程池 1.1 concurent.furtrue 开启进程,多进程&线程,多线程 # concurrent.futures创建并行的任务 # 进 ...
- python系列之 - 并发编程(进程池,线程池,协程)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- python 协程、I/O模型
一.引子 (超哥协程) 并发本质:保存状态+切换 cpu正在运行一个任务,转而执行另一个任务的情概况:1.是该任务发生了阻塞:2.该任务计算的时间过长或有一个优先级更高的程序替代了它. 协程本质上就是 ...
- Python3-协程
协程 引子 协程介绍 Greenlet Gevent介绍 Gevent之应用举例 一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需 ...
随机推荐
- ObjC: Foundation Kit
转自:http://marshal.easymorse.com/tech/objc-foundation-kit Foundation Kit是什么? 你可以把它看作Java JDK中的java.la ...
- ECharts将折线变平滑和去掉点的属性(转载)曲线变圆滑
本文链接:https://blog.csdn.net/sinat_36422236/article/details/62430114 series : [ { name:'your name', sy ...
- SpringBoot整合JavaWeb
一.SpringBoot整合Servlet的两种方式 1.通过注解扫描完成Servlet组件的注册 编写Servlet package com.example.demo.servlet; import ...
- InterpretML 微软可解释性机器学习包
InterpretML InterpretML: A Unified Framework for Machine Learning Interpretability https://github.co ...
- django url注册器组件, 响应器组件, 分页器组件
一.url注册器的使用 1.1导入模块 from django.urls import re_path, include from .serializer import views from rest ...
- WPF 用户控件的自定义依赖属性在 MVVM 模式下的使用备忘
依赖属性相当于扩充了 WPF 标签的原有属性列表,并可以使用 WPF 的绑定功能,可谓是十分方便的:用户控件则相当于代码重用的一种方式:以上几点分开来还是比较好理解的,不过要用到MVVM 模式中,还是 ...
- 实验十四 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 2016计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 团队名称 快活帮 作业学习目标 (1)掌握软 ...
- 22-C#笔记-预编译指令
基本和C++一致. 参考: http://www.runoob.com/csharp/csharp-preprocessor-directives.html
- MySQL 官方测试库
MySQL 官方测试库 github 地址 https://github.com/datacharmer/test_db MySQL 文档地址 https://dev.mysql.com/doc/em ...
- SWA2G422&485JK2G基础篇: 硬件使用说明
开发板板载介绍(当前使用的测试板,以后期最终版为准) 一,实物图 硬件说明 一,开发板主控芯片说明: 1. 单片机: STM32F103RET6 2. GPRS模块: Air202 二,开发板外设说明 ...