python-协程

python的协程,是一种协作(异步)工作方式;类似于多线程,但不是多线程,实际是在一个线程中工作;工作过程实际是利用协程模块(标准库asyncio),构建协程对象;当协程对象执行时,其中可以构造专属的等待方法,处于等待时,会调度其他的协程对象执行,当等待时间过后,又会恢复到原来的协程对象上来工作,类似于多线程的上下文切换,可以在使用维度上理解成微线程,特性如下:

1
2
3
4
协程是单线程异步的工作方式;能避免无意义的多线程切换;没有多线程的开销,因此能提升性能;
协程,没有多线程的锁机制,在一个线程中切换,因此效率会更高(性能);
协程不是多线程,不能利用cpu多核能力,不能实现并行,能实现并发;
必须自己来承担调度的责任(控制调度);

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import asyncio

async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")

async def main():
await asyncio.gather(say_hello(),say_hello(),say_hello())

asyncio.run(main())

:>Hello
:>Hello
:>Hello
//休眠1s
:>World
:>World
:>World

第三方协程框架gevent
它封装了libevent事件循环的API,因此能自动切换io操作;但是语法上好像不够清晰,写起来像是同步操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import gevent

def say_hello():
print("Hello")
#如需阻断,可使用gevent.sleep()
print("World")

g1=gevent.spawn(say_hello)
g2=gevent.spawn(say_hello)
g3=gevent.spawn(say_hello)

g1.join()
g2.join()
g3.join()

:>Hello
:>World
:>Hello
:>World
:>Hello
:>World

如需阻断,请查看备注代码

使用场景:
协程主要是为了允许在单线程中对 IO 密集的过程进行调度,它允许我们显式指定一个位置,程序可以从此处被挂起,转而执行其他任务,当 IO 结束时被调度,从当前位置返回然后处理结果。

总结:协程相对于多线程有明显的性能优势,因此在处理IO密集型操作时,一般使用协程而非多线程;但由于不能利用cpu多核,因此在处理计算密集型场景时,还是要优先考虑多进程/多进程+协程

欢迎关注我的其它发布渠道