【问题标题】:Avoid naming different asyncio tasks with the same variable to prevent unstoppable tasks避免使用相同的变量命名不同的异步任务,以防止无法停止的任务
【发布时间】:2023-03-17 01:41:01
【问题描述】:

我正在尝试创建一个实时编码环境,编码人员可以在其中创建和停止异步任务。

我用

启动了一个交互式 python 会话/asyncio REPL

python -m asyncio.

然后我允许用户按名称创建异步任务,例如:

import asyncio # executed with 'python -m asyncio' command

# simple async function
async def sleep(sleep_time):
    while True:
        print(f'sleeping for {sleep_time} seconds.')
        await asyncio.sleep(sleep_time)

x = asyncio.create_task(sleep(2))
y = asyncio.create_task(sleep(4))

这会创建两个异步运行的任务,x 和 y。

这些任务可以很容易地停止

x.cancel()y.cancel()

但是如果用户在执行x.cancel()之前执行了一个同名x = asyncio.create_task(sleep(3))的新任务,两个“x”任务将同时运行。 x.cancel() 将停止 x 的最后定义(睡眠 3 秒),但 x 的原始定义——睡眠 2 秒——仍将运行。没有简单的方法可以停止仍在后台运行的 x 任务。 x.cancel() 返回 False 而不是 True

如果用户不小心两次使用相同的变量名,我的目标是避免在后台运行不可停止的任务。有没有办法阻止用户将新定义分配给x 变量?还是更好的策略?

asyncio 特定或基础 Python 解决方案都是可接受的。

谢谢。

【问题讨论】:

    标签: python ipython python-asyncio


    【解决方案1】:
    if "x" in globals():
        x.cancel()
        del x
    

    这样的东西可能有用吗? if "x" in globals(): 检查 x 是否已定义,del x "undefines" x

    或者也许使用try:如果x没有定义,做一个取消并捕获NameError异常

    try:
        x.cancel()
    except NameError:
        ...
    

    如果你只是想prevent the user from launching a new task with the same name as an existing task,同样的技术仍然可以使用,也许是类似的东西:

    if "x" in globals():
        if not x.done():
           print(" Another task with the same name is running... ")
        else:
           x = asyncio.create_task(sleep(3))
    else:
        x = asyncio.create_task(sleep(3))
    
    

    【讨论】:

    • 这是一个很酷的技术,但我并不想阻止由于停止未定义的进程而导致的错误。我试图阻止用户启动与现有任务同名的新任务。
    • 不会像if 'x' in globals() 这样的东西仍然有效吗?请参阅我编辑的答案。
    • 不完全,但我很感激。我想我需要将asyncio.create_task(sleep(3)) 包装在一个函数/类中,如果globals() 中存在等号的左侧(x),它会以某种方式引发错误。不确定这是否可能!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2011-07-22
    • 1970-01-01
    相关资源
    最近更新 更多