怎么在python中使用协程实现并发?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
<强>协程强>
协程是一种用户态的轻量级线程,又称微线程。
协程拥有自己的寄存器上下文和栈,调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
<>强优点:强>
- <李>
无需线程上下文切换的开销
李> <李>无需原子操作锁定及同步的开销
李> <李>方便切换控制流,简化编程模型
李> <李>高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题,所以很适合用于高并发处理。
李>所谓原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何上下文切换(切换到另一个线程)。
原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。
<强>缺点:强>
- <李>
无法利用多核资源:协程的本质是个单线程,它不能同时将单个CPU的多个核用上,协程需要和进程配合才能运行在多CPU上。当然我们日常所编写的绝大部分应用都没有这个必要的,除非是CPU密集型应用。
李> <李>进行阻塞(阻塞)操作(如IO时)会阻塞掉整个程序
李><强>使用Gevent 强>
Gevent是python的一个并发框架,以微线程一种绿色小鸟为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效。
- <李>
<强>简单示例强>
李>gevent的睡眠可以交出控制权,当我们在受限于网络或IO的函数中使用gevent,这些函数会被协作式的调度,gevent的真正能力会得到发挥.Gevent处理了所有的细节,来保证你的网络库会在可能的时候,隐式交出一种绿色小鸟上下文的执行权。
import gevent def foo (): 打印才能(& # 39;running 拷贝foo # 39;) gevent.sleep才能(0) 打印才能(& # 39;com back 得到bar 拷贝用foo # 39;) def 酒吧(): 打印才能(& # 39;running 拷贝酒吧# 39;) gevent.sleep才能(0) 打印才能(& # 39;com back 得到foo 拷贝用酒吧# 39;) #,创建线程并行执行程序 gevent.joinall ([ gevent.spawn才能(foo), gevent.spawn才能(bar), ])
执行结果
运行在foo
引用>
com运行在酒吧从酒吧里从foo foo
com在酒吧<李>
<强>同步异步强>
李>import 随机的 import gevent def 任务(pid): gevent.sleep才能(random.randint (0, 2), *, 0.001) 打印才能(& # 39;Task % s 完成# 39;,%,pid) def 同步(): for 才能小姐:拷贝范围(1,10): ,,,的任务(我) def 异步(): threads 才能=,[gevent.spawn(任务,,i), for 小姐:拷贝范围(10)) gevent.joinall才能(线程) 打印(& # 39;同步:& # 39;) 同步() 打印(& # 39;异步:& # 39;) 异步()执行输出
同步:
引用>
任务1完成
任务2做
3
任务完成4
完成任务5
完成任务6
完成任务做7
8
任务完成9完成异步:
任务1完成
Task 4做任务5
完成任务9
完成任务做6
0
完成任务2
完成任务3
任务完成7 8日
任务完成了<李>
<强>以子类的方法使用协程强>
李>可以子类化一种绿色小鸟类,重载它的_run方法,类似多线程和多进程模块
import gevent 得到gevent import 一种绿色小鸟 class 测试(一种绿色小鸟): def 才能;__init__(自我,,消息,,n): ,,,Greenlet.__init__(自我) ,,,self.message =,消息 ,,,self.n =n def 才能_run(自我): ,,,print (self.message, & # 39;开始# 39;) ,,,gevent.sleep (self.n) ,,,print (self.message, & # 39;结束# 39;) tests =, ( 测试才能(“hello",, 3), 测试才能(“world",, 2), ] for test 拷贝测试: test.start才能(),#,启动 for test 拷贝测试: test.join才能(),#,等待执行结束怎么在python中使用协程实现并发