MegaMU个人站

欢迎光临

落日黄沙 白帆秋水 你可知谁的记忆在时空里飞?


协程基础

目录

协程

线程数量非常多的时候,会有两个问题:一是系统线程会占用非常多的内存空间,二是过多的线程切换会占用大量的系统时间。
协程刚好可以解决上述2个问题。协程运行在线程之上,当一个协程执行完成后,可以选择主动让出,让另一个协程运行在当前线程之上。
协程并没有增加线程数量,只是在线程的基础之上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多。

def work1():
    while True:
        print("work1:...")
        yield
        
def work2():
    while True:
        print("work2:...")
        yield
        
if __name__ == "__main__":
    w1 = work1()
    w2 = work2()
    while True:
        next(w1)
        next(w2)

使用greenlet实现协程

 from greenlet import greenlet
 import time
 
 def work1():
     while True:
         print("work1:...")
         time.sleep(0.5)
         g2.switch() # g1阻塞执行g2
         
 def work2():
     while True:
         print("work2:...")
         time.sleep(0.5)
         g1.switch() # g2阻塞执行g1
         
 if __name__ == "__main__":
     g1 = greenlet(work1)
     g2 = greenlet(work2)
     # g1先执行
     g1.switch()

使用greenlet无需yield,使用switch()来切换协程或启动协程。协程内的switch()会在阻塞时启用。
指定一个先执行后,就可以自动执行其他协程。

使用gevent实现协程

指派任务:gevent(函数名,参数1,参数2,...)

之后使用.join()来是主线程等待协程执行完毕再退出。使用gevent.sleep()来阻塞协程、切换协程。

import gevent
import time

def work1():
    while True:
        print("work1:...")
        gevent.sleep(0.5)
              
def work2():
    while True:
        print("work2:...")
        gevent.sleep(0.5)
        
if __name__ == "__main__":
    g1 =  gevent.spawn(work1)
    g2 = gevent.spawn(work2)
    g1.join()
    g2.join()

默认情况下使用 time.sleep()是不行的哦!除非:给gevent或程序打补丁

# 给程序打补丁,放在程序开头。
# 放在下面也不一定报错,但可能影响其他模块
from gevent import monkey
monkey.patch_all()

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦