协程,又称微线程。英文名Coroutine。协程是Python语言中所特有的,在其他语言中没有。
协程是python中另外一种实现多任务的方式,比线程更小、占用更小执行单元(理解为需要的资源)。
在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行。
协程就是通过yield来实现多个任务之间的切换的。
进程、线程、协程对比
1.进程切换需要的资源最大,效率很低。
2.线程切换需要的资源一般,效率一般,介于进程和协程之间(在不考虑GIL的情况下)。
3.协程切换任务资源很小,效率高。
注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己决定。
在实现多任务时, 线程切换从系统层面远不止保存和恢复CPU上下文那么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。
python2
gevent 1.2.2
from gevent import joinall, spawn
import time
from gevent import monkey
monkey.patch_all()
threads = []
def functionA(a):
time.sleep(a)
return a*a
print "current time:", time.time()
list = [1,2,3,4,5]
for a in list:
result = spawn(functionA, a)
threads.append(result)
joinall(threads)
for result in threads:
print result.value
print "current time:", time.time()
运行结果:
current time: 1571744070.42
1
4
9
16
25
current time: 1571744075.43
gevent模块中提供了一个monkey补丁,帮我实现将耗时代码换成gevent自己实现的模块。
所以在上面的代码中加上了
from gevent import monkey
monkey.patch_all()
假设不加上这小段代码,那么总耗时将是 1+2+3+4+5=15秒的时间。
使用gevent,可以获得极高的并发性能,但gevent只能在Unix/Linux下运行,在Windows下不保证正常安装和运行。
实现协程的方式,不止gevent,还可以:
(1)使用greenlet实现协程,进行手动切换
(2)使用yield实现协程
参考文章:
- https://www.liaoxuefeng.com/wiki/897692888725344/966405998508320
- https://blog.51cto.com/14335413/2411359