回调函数实现异步
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()
运行结果
