【tornado】11.tornado异步

回调函数实现异步

import time
import threading

def timeconsuming(callback):
    def run(cb):
        print("开始处理耗时程序")
        time.sleep(5)
        print("耗时程序处理完毕")
        cb("【耗时程序已经处理完,处理结果是ok】") # 将程序运行返回的结果返回给回调函数finish
    threading.Thread(target=run,args=(callback,)).start()


# 回调函数(用于接收线程返回的结果)
def finish(data):
    print("回调函数启动")
    print("接收到来自线程的返回结果为:",data)
    print("回调函数结束")

def reqA():
    print("开始处理事件A")
    timeconsuming(finish)
    print("事件A处理完毕")

def reqB():
    print("开始处理事件B")
    time.sleep(2)
    print("事件B处理完毕")

def main():
    reqA()
    reqB()

if __name__ == '__main__':
    main()
  • main函数中有两个请求reqA和reqB,请求A会启动一个耗时程序timeconsuming,同时reqA在timeconsuming函数中加入了回调请求finish
  • 当timeconsuming执行完后,会自动执行回调函数finish
    回调函数finish中的参数是timeconsuming中通过cb传入的参数:
    【耗时程序已经处理完,处理结果是ok】
运行结果

在这里插入图片描述



协程实现异步

1.通过实现一个生成器来实现协程异步
import time
import threading

def timeconsuming():
    def run():
        print("开始处理耗时程序")
        time.sleep(5)
        try:
            global gen
            gen.send("【耗时程序已经处理完,处理结果是ok】")
        except StopIteration as e:
            pass
    threading.Thread(target=run).start()

def reqA():
    print("开始处理事件A")
    res=yield timeconsuming()
    print("接收到来自线程的返回结果为:",res)
    print("事件A处理完毕")

def reqB():
    print("开始处理事件B")
    time.sleep(2)
    print("事件B处理完毕")

def main():
    global gen
    gen=reqA() # 生成一个生成器
    next(gen)  #执行这个生成器
    reqB()

if __name__ == '__main__':
    main()
  • 通过生成器gen来实现请求A
  • 在执行reqA时,会执行到res=yield timeconsuming()这一句,然后挂起,等待timeconsuming()返回结果
  • 另一反面,开始执行main函数中的reqB,事件B会顺利地执行完
  • 在执行函数timeconsuming时,会返回这个耗时程序部分的处理结果:
    【耗时程序已经处理完,处理结果是ok】
  • 事件A在收到函数timeconsuming返回的结果后被唤醒,继续执行reqA中剩下的部分
运行结果:

在这里插入图片描述

2. 通过装饰器的方式实现协程异步
import time
import threading

def timeconsuming():
    def run():
        print("开始处理耗时程序")
        time.sleep(5)
        try:
            global gen
            gen.send("【耗时程序已经处理完,处理结果是ok】")
        except StopIteration as e:
            pass
    threading.Thread(target=run).start()

def genCoroutine(func):
    def wrapper(*args,**kwargs):
        global gen
        gen=func()
        next(gen)
    return wrapper

@genCoroutine
def reqA():
    print("开始处理事件A")
    res=yield timeconsuming()
    print("接收到来自线程的返回结果为:",res)
    print("事件A处理完毕")

def reqB():
    print("开始处理事件B")
    time.sleep(2)
    print("事件B处理完毕")

def main():
    reqA()
    reqB()

if __name__ == '__main__':
    main()
运行结果:

在这里插入图片描述

3.一个看不懂的版本实现异步
import time
import threading

def timeconsuming():
     print("开始处理耗时程序")
     time.sleep(5)
     print("结束耗时程序")
     yield "【耗时程序已经处理完,处理结果是ok】"

def genCoroutine(func):
    def wrapper(*args,**kwargs):
        gen1=func()   #reqA的生成器
        gen2=next(gen1) # timeconsuming的生成器
        def run(g):
            res=next(g)
            try:
                gen1.send(res) # 返回数据给reqA
            except StopIteration as e:
                pass
        threading.Thread(target=run,args=(gen2,)).start()
    return wrapper

@genCoroutine
def reqA():
    print("开始处理事件A")
    res=yield timeconsuming()
    print("接收到来自线程的返回结果为:",res)
    print("事件A处理完毕")

def reqB():
    print("开始处理事件B")
    time.sleep(2)
    print("事件B处理完毕")

def main():
    reqA()
    reqB()

if __name__ == '__main__':
    main()
运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/AXIMI/article/details/86546547