Python - 协程 - Gevent - yield
来源:互联网 发布:3d建模 软件 编辑:程序博客网 时间:2024/04/29 08:55
Python在并发处理上不仅提供了多进程和多线程的处理,还包括了协程。
协程很类似于Javascript单线程下异步处理的概念,协程同样是单线程的,之所以能够进行并发是因为通过某种方式保存了执行栈的上下文,在一定条件下将执行权交由其他栈,在一定条件下又通过执行栈上下文恢复栈。
1. yield
与之一概念最为类似的是Python中的yield
class DemoTwo: @staticmethod def run(): def gen(max): n = 0 while n < max: yield n n += 1 my_numbers = gen(10) for number in my_numbers: print(number)
带有yield的函数,已经不是一个普通的函数,这样的函数会返回一个“生成器”,这个生成器类似于迭代器(所以它可以被for使用),这个生成器也就是上文中的my_numbers有一个next()方法,用于取出下一个数。
表面上,我们可以看做my_numerbs保存了0-9,通过yield我们将这些数保存下来了,在我们进行迭代的时候他才会取出这些数。
实际上,这是一种错觉,如果只是单纯地保存执行结果,那yield看似并没有我们所想的强大。
我们来作一个实验来看看他到底是怎么样的:
class DemoTwo: @staticmethod def run(): def gen(max): n = 0 while n < max: print('start',n) yield n print('end',n) n += 1 my_numbers = gen(10) my_numbers.__next__() my_numbers.__next__()
我们可以看到输出 (DemoTwo.run())
start 0end 0start 1
也许到了现在我们可以理解yield了。
yield相当于一个中断,将执行权交给了其他函数,同时将自己的栈上下文保存到了生成器中。
而在调用函数内next()方法则相当于还原了栈上下文并继续执行,直到下一个yield,又发生了一次中断。
再来看下面一段代码:
class DemoTwo: @staticmethod def run(): def gen(max): n = 0 while n < max: print('start',n) a = yield n print(a) print('end',n) n += 1 my_numbers = gen(10) my_numbers.__next__() my_numbers.send('test')
yield并不仅仅可以传递一个参数,也可以接受一个参数,通过send的方法,我们可以灵活地与yield函数进行交互。
也许next可以看作next(None) (在python3中已经没有next(),取而代之的是__next__(),当然send已经足够了)
yield是一个不完全的协程实现,那么来总结一下:
1. 协程是一种并发的能力
2. 协程是单个线程内的表现
3. 协程通过程序保存上下文、执行等行为
和线程对比:
1. 协程没有线程切换开销
2. 单线程没有锁机制
2. gevent
from gevent import monkeymonkey.patch_socket()
import geventfrom gevent.event import Event'''Illustrates the use of events'''evt = Event()def setter(): '''After 3 seconds, wake all threads waiting on the value of evt''' print('A: Hey wait for me, I have to do something') gevent.sleep(3) print("Ok, I'm done") evt.set()def waiter(): '''After 3 seconds the get call will unblock''' print("I'll wait for you") evt.wait() # blocking print("It's about time")def main(): gevent.joinall([ gevent.spawn(setter), gevent.spawn(waiter), gevent.spawn(waiter), gevent.spawn(waiter), gevent.spawn(waiter), gevent.spawn(waiter) ])if __name__ == '__main__': main()
- Python - 协程 - Gevent - yield
- Python gevent协程
- 协程-gevent(python版)
- python gevent
- python-gevent
- python gevent
- python gevent
- 【python学习笔记】Python实现协程yield方法和gevent库
- python yield协程
- Python:yield协程
- python--yield>>>协程
- [python协程gevent]之greenlet初识
- python generator yield 协程 coroutine
- python协程:yield的使用
- Python基础-协程 yield关键字
- 安装gevent For Python
- python gevent 安装
- python安装gevent
- 将十进制转化为十六进制和二进制
- 微信小程序课程目录
- 关于View的onMeasure()、onSizeChanged()、onLayout()、onDraw()调用顺序
- android 实用知识点
- sqlserver跨服务器备份表数据
- Python - 协程 - Gevent - yield
- 狡猾的几道PHP试题,试试看看你会不会也掉入陷阱
- 微信开发学习随笔(未整理)
- 怎么把word转换成excel表格的格式
- Registry key 'Software\JavaSoft\Java Runtime Environment\CurrentVersion'
- 设计模式-简单工厂模式
- eclipse的运行需要JDK吗?
- 【腾讯TMQ】内存泄漏漫谈
- Fix 探索之路 —— 手Q热补丁轻量级方案