python多任务之协程

2019-06-10  本文已影响0人  rookieyu

协程,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行 通俗理解只要在def里面只看到一个yield关键字表示就是协程

协程是也是实现多任务的一种方式

协程yield

协程之间执行任务按照一定顺序交替执行

demo:

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)    #调用生成器,增加yield是将一个函数转变为一个生成器,使用next可以调用

        next(w2)

main()

生成器、装饰器、迭代器详解见:

协程greenlet

使用的较少

    为了更好使用协程来完成多任务,python中的greenlet模块对其封装,从而使得切换任务变的更加简单,但是还不够简单这里不做过多介绍了。

    greenlet已经实现了协程,但是这个还要人工切换,这里介绍一个比greenlet更强大而且能够自动切换任务的第三方库,那就是gevent。

协程gevent

gevent内部封装的greenlet,其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。

由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO

import gevent

import time

from gevent import monkey

# 打补丁,让gevent框架识别耗时操作,比如:time.sleep,网络请求延时

monkey.patch_all()

def work1(n):

    for i in range(n):

        print("work1....")

        time.sleep(0.2)

            # 获取当前协程

        print(gevent.getcurrent(), i)

def work2(n):

    for i in range(n):

        print("work2....")

        time.sleep(0.2)

            # 获取当前协程

        print(gevent.getcurrent(), i)

g1 = gevent.spawn(work1,5)

g2 = gevent.spawn(work2,5)

g1.join()

g2.join()

当前程序是一个死循环并且还能有耗时操作,就不需要加上join方法了,因为程序需要一直运行不会退出。如果不增加join那么主进程结束那么协程会停止运行

上一篇 下一篇

猜你喜欢

热点阅读