python - 与 asyncio 一起运行阻塞和解除阻塞任务
问题描述
我想异步运行阻塞和解除阻塞任务。显然,有必要使用 run_in_executor 方法来阻止来自 asyncio 的任务。这是我的示例代码:
import asyncio
import concurrent.futures
import datetime
import time
def blocking():
print("Enter to blocking()", datetime.datetime.now().time())
time.sleep(2)
print("Exited from blocking()", datetime.datetime.now().time())
async def waiter():
print("Enter to waiter()", datetime.datetime.now().time())
await asyncio.sleep(3)
print("Exit from waiter()", datetime.datetime.now().time())
async def asynchronous(loop):
print("Create tasks", datetime.datetime.now().time())
task_1 = asyncio.create_task(waiter())
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
task_2 = loop.run_in_executor(executor, blocking)
tasks = [task_1, task_2]
print("Tasks are created", datetime.datetime.now().time())
await asyncio.wait(tasks)
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(asynchronous(loop))
except (OSError) as exc:
sys.exit('Exception: ' + str(exc))
我应该使用相同的事件循环来阻止 run_in_executor 中的任务,还是必须使用另一个?我应该在我的代码中进行哪些更改以使其异步工作?谢谢
解决方案
您必须使用相同的循环。循环委托给执行程序,执行程序运行任务是事件循环的独立线程。所以你不必担心你的阻塞任务会阻塞事件循环。如果您使用单独的循环,则事件循环中的异步函数将无法等待阻塞在新循环中运行的函数的结果。
事件循环通过创建代表执行者任务的未来来管理这一点。然后它在其中一个执行器线程中运行阻塞任务,并且当执行器任务返回时,设置未来的结果并将控制返回到事件循环中的等待函数(如果有)。
推荐阅读
- c# - 没有给出对应于所需格式参数错误的参数
- c# - 如何创建与另一个类的多个关系作为不同的属性?
- javascript - 在本机反应中顺序运行功能
- json - 如何使用 TypeScript 的模板文字类型改进作用域字典的类型检查?
- angular - 如何在“.subscribe()”Angular/Jasmine 中测试代码
- python - ExifTags 的 .get 函数 - 它是什么?
- ios - Swift 5.3.2:符合 Objective-C 协议且属性定义为 @optional 的对象始终是不可变的
- python - 使用 Python 和 Azure 函数的 Xero API Webhook 服务器
- rest - 哪个 HTTP 请求在服务器上执行命令?
- checkout - Magento 2 如何在结帐页面中添加两个不同的标签