Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 异步任务取消_Python_Python Asyncio_Cancellation - Fatal编程技术网

Python 异步任务取消

Python 异步任务取消,python,python-asyncio,cancellation,Python,Python Asyncio,Cancellation,这是我创建的一个测试脚本,用于更好地理解任务取消- 导入异步IO 随机输入 输入信号 导入回溯 异步def关闭(signame,循环): 打印(“关闭”) tasks=[asyncio.task.all_tasks()中任务对应的任务] 对于任务中的任务: task.cancel() 尝试: 等待任务 除asyncio.Cancelled错误外: 打印(“任务已取消:%s”,任务) loop.stop() 异步定义另一个() 等待异步睡眠(2) 异步定义某些其他进程(): 等待异步睡眠(5) 返

这是我创建的一个测试脚本,用于更好地理解任务取消-

导入异步IO
随机输入
输入信号
导入回溯
异步def关闭(signame,循环):
打印(“关闭”)
tasks=[asyncio.task.all_tasks()中任务对应的任务]
对于任务中的任务:
task.cancel()
尝试:
等待任务
除asyncio.Cancelled错误外:
打印(“任务已取消:%s”,任务)
loop.stop()
异步定义另一个()
等待异步睡眠(2)
异步定义某些其他进程():
等待异步睡眠(5)
返回“我”
异步def进程(作业、循环、i):
印刷品(一)
task=loop.create_任务(some_other_进程())
值=等待任务
如果i<1:
另一个任务=循环。创建任务(另一个()
等待另一项任务
#等待一些其他过程()
def拉力(回路):
i=0
尽管如此:
job=f“随机整数-{random.randint(01100)}”
尝试:
循环。运行_直到_完成(进程(作业、循环、i))
i+=1
除asyncio.Cancelled错误外,错误为e:
打印(“任务取消”)
打破
除例外情况外:
打印(traceback.format_exc())
#asyncio.get_event_loop().stop()
def main():
尝试:
loop=asyncio.get\u event\u loop()
对于['SIGINT']中的signame:
loop.add\u信号\u处理程序(
getattr(信号,符号名称),
lambda:asyncio.确保未来(关机(信号名,循环))
)
尝试:
拉(环)
除例外情况外:
打印(traceback.format_exc())
最后:
loop.close()
最后:
打印(“完成”)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
我不明白为什么我看到-

任务已销毁,但它处于挂起状态!
任务:
这里使用
asyncio。确保您为
shutdown
corroutine创建了任务,但您不需要在任何地方等待该任务的完成。稍后,当您关闭事件循环时,它会警告您此任务处于挂起状态


Upd:

如果您想做一些提示,最好的地方就是在
loop.close()之前,不管脚本结束的原因是什么(信号、异常等)

尝试以这种方式更改代码:

# ...

async def shutdown(loop):  # remove `signal` arg

# ...

def main():
    try:
        loop = asyncio.get_event_loop()
        try:
            pull(loop)
        except Exception:
            print(traceback.format_exc())
        finally:
            loop.run_until_complete(shutdown(loop))  # just run until shutdown is done
            loop.close()
    finally:
        print("Done")

# ...

Upd2:

如果您仍然需要信号处理程序,可能需要执行以下操作:

from functools import partial

loop.add_signal_handler(
    getattr(signal, signame),
    partial(cb, signame, loop)
)

def cb(signame, loop):
    loop.stop()
    loop.run_until_complete(shutdown(signame, loop))

我在哪里等待它?我需要做的是在
sigint
的情况下取消任务,因此我需要信号处理器最新更改的两个问题-
运行时错误:事件循环在将来完成之前停止。
任务已销毁,但它处于挂起状态用于
coro=
from functools import partial

loop.add_signal_handler(
    getattr(signal, signame),
    partial(cb, signame, loop)
)

def cb(signame, loop):
    loop.stop()
    loop.run_until_complete(shutdown(signame, loop))