怎么在python中使用协程实现并发

  介绍

怎么在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中使用协程实现并发