令我惊讶的是,run_in_executor()
库的asyncio
方法属于一个loop
对象。
特别是,如果我选择通过import threading
,t = threading.Thread(target=...)
,t.start()
以“通常”的方式在异步事件循环的同时运行第二个线程,会有什么不同? / p>
也许答案是通过使用asyncio
模块,如果循环知道其他线程,那么可以在运行时进行低级优化吗?
答案 0 :(得分:2)
您总是可以手动启动另一个线程,但是您有责任使其工作,例如使用队列。在Python 3 concurrent.futures
中,提供了一个方便的API,用于将任务卸载到线程池。 submit
方法接受一个函数,将其提供给池中的线程以运行它,并立即返回一个句柄,该句柄将在准备好后提供结果(或传播异常)。
run_in_executor
就是要为异步带来便利。通常,您不应该在asyncio内部运行阻塞代码-甚至禁止使用time.sleep()
之类的简单代码,因为它会阻塞整个事件循环。 run_in_executor
允许您违反该规则。例如:
async def sleep_test():
loop = asyncio.get_event_loop()
print('going to sleep')
await loop.run_in_executor(None, time.sleep, 5)
#time.sleep(5)
print('waking up')
asyncio.run(asyncio.gather(sleep_test(), sleep_test()))
运行此代码显示协程的两个实例并行睡眠。如果我们直接使用time.sleep()
,它们将连续睡眠,因为睡眠会阻塞事件循环。
这个示例当然很愚蠢,因为有asyncio.sleep()
能有效地完成整个过程,但是它显示了基本思想。 run_in_executor
的实际用例包括: