介绍几种Python异步执行的方式
参考:
通过 threading.Thread 实现
先将需要异步执行的函数用线程的方式包装为一个装饰器,然后拿去装饰需要异步执行的函数即可。
下面构造两个函数
from threading import Thread
from time import sleep
import numpy as np
import pandas as pd
def async_call(func):
def wrapper(*args, **kwargs):
thr = Thread(target=func, args=args, kwargs=kwargs)
thr.start()
return wrapper
@async_call
def A(x1, x2, i):
data = pd.DataFrame(np.random.randn(x1, x2))
sleep(2)
data.to_csv('data_{}.csv'.format(i))
print ('data_{} save done.'.format(i))
def B(i):
print ('B func ', i)
if __name__ == "__main__":
for i in range(10):
A(1000, 1000, i)
B(i)
A 函数用 async_call 进行装饰,根据输入的形状创建数组并保存。
B 函数不进行装饰,打印输入的值
起一个循环,连续顺序执行10次A和B。
可以看到程序首先吊起了10个线程去执行A函数,不必等待A函数执行完毕,先输出B函数的打印信息“B func i”,随后这10个线程的命令分别执行完毕,并打印出相关信息“data_i save done.”。在当前目录保存了10个文件 "data_1.csv", "data_2.csv"... 。
通过 yield 实现协程
yield 可以让程序暂停运行,等待主程序发送数据,下次继续再yield处暂停。下面看一个例子通过yield实现协程。
使用yeild实现的协程时需要先用next激活,才能使用send发送数据。
next时会产生yield右边的数据,也就是name。
send时接收值的是yield左边的数据,也就是x。
协程结束时会抛出StopIteration。
def coroutine_example(name):
print ('start croutine name:{}'.format(name))
x = yield name
print ('send value:{}'.format(x))
if __name__ == "__main__":
coro = coroutine_example('hi')
print (next(crou))
print (coro.send(1))
输出结果:
start croutine name:hi
hi
send value:1
Exception has occurred: StopIteration
File "C:\Users\Administrator\Desktop\test\async_test.py", line 43, in
print (crou.send(1))
yield from 说明
yield from 和for 循环类似,yield from x 内部先调用iter(x),然后调用next()获取x中的value。此处x为任意可迭代对象。
下面