文章目录[隐藏]
最近总是接触到协程这个概念,每次碰到都比较懵逼。就尝试去了解这个进线程之外的奇怪家伙,最后看了一下也不太难,简单说就是一个微线程。
说明
- 协程,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行。
实现方法
- 个人目前主要技术语言都是Python,所以以下都是基于Python编写的。
协程yield的代码实现
- 通俗理解只要在def里面只看到一个yield关键字表示就是协程。
import time
def work1():
while True:
print("----work1---")
yield
time.sleep(0.5)
def work2():
while True:
print("----work2---")
yield
time.sleep(0.5)
def main():
w1 = work1()
w2 = work2()
while True:
next(w1)
next(w2)
if __name__ == "__main__":
main()
greenlet实现
- 安装
pip install greenlet
- 实现
import time
import greenlet
# 任务1
def work1():
for i in range(5):
print("work1...")
time.sleep(0.2)
# 切换到协程2里面执行对应的任务
g2.switch()
# 任务2
def work2():
for i in range(5):
print("work2...")
time.sleep(0.2)
# 切换到第一个协程执行对应的任务
g1.switch()
if __name__ == '__main__':
# 创建协程指定对应的任务
g1 = greenlet.greenlet(work1)
g2 = greenlet.greenlet(work2)
# 切换到第一个协程执行对应的任务
g1.switch()
gevent
- 安装
pip install gevent
- 实现
import gevent
import time
from gevent import monkey
# 打补丁,让gevent框架识别耗时操作,比如:time.sleep,网络请求延时
monkey.patch_all()
# 任务1
def work1(num):
for i in range(num):
print("work1....")
time.sleep(0.2)
# gevent.sleep(0.2)
# 任务1
def work2(num):
for i in range(num):
print("work2....")
time.sleep(0.2)
# gevent.sleep(0.2)
if __name__ == '__main__':
# 创建协程指定对应的任务
g1 = gevent.spawn(work1, 3)
g2 = gevent.spawn(work2, 3)
# 主线程等待协程执行完成以后程序再退出
g1.join()
g2.join()
进程、线程、协程之间的关系
- 一个进程至少有一个线程,进程里面可以有多个线程
- 一个线程里面可以有多个协程
进程、线程、线程的对比
- 进程是资源分配的单位
- 线程是操作系统调度的单位
- 进程切换需要的资源最大,效率很低
- 线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下)
- 协程切换任务资源很小,效率高
- 多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发
小结
- 进程、线程、协程都是可以完成多任务的,可以根据自己实际开发的需要选择使用
- 由于线程、协程需要的资源很少,所以使用线程和协程的几率最大
- 开辟协程需要的资源最少
参考
注意参考的6.3节,个人执行结果和参考文章不太一致。