python-3.x - Python (3.7) asyncio,带有 while 循环和自定义信号处理程序的工作任务
问题描述
我试图了解无限期运行 asyncio 任务的模式以及自定义循环信号处理程序的不同之处。我使用创建工人,loop.create_task()
以便他们同时运行。
在我的普通工人代码中,我正在轮询数据并在数据存在时采取相应的行动。
我正在尝试在信号上优雅地处理关闭过程。传递信号时 - 我再次create_task()
使用关闭功能,以便当前正在运行的任务继续,并且在事件循环的下一次迭代中执行关闭。现在 - 当单个工作while
循环实际上没有执行任何 IO 或工作时,它会阻止信号处理程序被执行。它永远不会结束并且不会返回执行以便可以运行其他任务。
当我没有将自定义信号处理程序附加到循环并运行该程序时,会传递一个信号并且程序停止。我认为这是一个停止循环本身的主线程。这显然与尝试在运行循环上安排(新)关闭任务不同,因为该运行循环被卡在单个协程中,该协程被阻塞在 while 循环中,并且不会为其他任务提供任何控制或时间。
这种情况有什么标准模式吗?asyncio.sleep()
如果没有工作要做,我是否需要用其他东西替换while循环(例如重新安排工作功能本身)?
如果range(5)
替换为,range(1, 5)
那么所有工作人员都会等待 asyncio.sleep,但如果其中一个没有,那么一切都会被阻止。这种情况如何处理,有没有标准的做法?
下面的代码说明了这个问题。
async def shutdown(loop, sig=None):
print("SIGNAL", sig)
tasks = [t for t in asyncio.all_tasks()
if t is not asyncio.current_task()]
[t.cancel() for t in tasks]
results = await asyncio.gather(*tasks, return_exceptions=True)
# handle_task_results(results)
loop.stop()
async def worker(intval):
print("start", intval)
while True:
if intval:
print("#", intval)
await asyncio.sleep(intval)
loop = asyncio.get_event_loop()
for sig in {signal.SIGINT, signal.SIGTERM}:
loop.add_signal_handler(
sig,
lambda s=sig: asyncio.create_task(shutdown(loop, sig=s)))
workers = [loop.create_task(worker(i)) for i in range(5)] # this range
loop.run_forever()
解决方案
推荐阅读
- c# - System.Drawing.Image 自己的实现
- typescript - 如何配置 tsc 以将输出重定向到不同的文件夹?
- docker - 无法从自己的私有 docker repo 中提取图像
- javascript - angularJS 无法从登录页面重定向到散列路由
- gremlin - Gremlin 是否支持 none() 步骤?
- matlab - matlab fmincon优化中没有足够的输入参数错误
- python - 我正在尝试猜测单词游戏,但是当它选择具有两个或多个相同字母的随机单词时出现逻辑错误
- ispconfig - 如何在 ISPConfig 中设置反向代理?
- python - 如何根据第一个元素以各种方式配对列表列表
- php - Laravel 8 - 具有两个不同注册表单的多重身份验证?