【问题标题】:How to pause an asyncio created task using a lock or some other method?如何使用锁或其他方法暂停异步创建的任务?
【发布时间】:2020-04-11 06:07:04
【问题描述】:

这是我尝试在主项目中执行的示例程序,但主要思想是我使用 asyncio.create_task 创建了一个任务。当某些事件发生时,我想稍后在代码中暂停该任务。在此示例代码中,asyncio.create_task 启动 task_tic_tock 并打印“tic-tock”。稍后在代码中,当 other_task 的计数可被 3 整除时,它会获取锁并启动 task_tic_tock,参数为 False。我不确定锁是最好使用的东西,但我希望的行为是让它打印“In new count”和“print val is now false”,而不是“tic-”tock”。曾经锁定结束我希望它恢复打印“tic_tock”。

import asyncio

lock = asyncio.Lock()

def task_tic_tock(print_val):
    if print_val:
        print("tic-tock")
    else:
        print("Print val is now false")

async def start_tic_tock(print_val):
    while True:
        task_tic_tock(print_val)
        await asyncio.sleep(1)

async def other_task():
    count = 0
    while True:
        count = count + 1
        if count % 3 == 0:
            async with lock:
                task_tic_tock(False)
                new_count = 5
                while new_count > 0:
                    print("In new count")
                    new_count = new_count - 1
                    await asyncio.sleep(1)
        await asyncio.sleep(1)
    print("Other task running")
    await asyncio.sleep(1)

async def main():
    print_val = asyncio.create_task(start_tic_tock(True))
    await asyncio.gather(other_task(), print_val)


asyncio.run(main())

create_task 是如何工作的,是否可以在另一个任务正在进行时暂停它一段时间?任何帮助将不胜感激!

【问题讨论】:

    标签: python-3.x async-await python-asyncio


    【解决方案1】:

    你可以用一把锁来实现你想要的。您的代码的问题是您永远不会获得start_tic_tock 中的锁,因此您无法根据您在other_task 中获得的锁来“暂停”该协程。

    您可以通过使您的 start_tic_tock 方法获取锁来解决此问题,如下所示:

    async def start_tic_tock(print_val):
       while True:
           async with lock:
               task_tic_tock(print_val)
               await asyncio.sleep(1)
    

    也就是说Event 可能更适合您的需求。事件明确用于在满足条件时通知任务。下面是使用事件的完整代码。请注意,当您像在上述代码中那样全局创建EventLock 时,您可能会创建一个新的事件循环。 asyncio.run 总是创建一个新循环,这意味着您可以运行两个循环,这可能会导致异常。在下面我明确地创建了一个循环来避免这些错误,你需要重构一下以再次使用asyncio.run

    import asyncio
    
    loop = asyncio.new_event_loop()
    event = asyncio.Event(loop=loop)
    
    async def start_tic_tock(print_val):
        while True:
            await event.wait()
            task_tic_tock(print_val)
            await asyncio.sleep(1)
    
    async def other_task():
        count = 0
        while True:
            count = count + 1
            if count % 3 == 0:
                event.clear()
                task_tic_tock(False)
                new_count = 5
                while new_count > 0:
                    print("In new count")
                    new_count = new_count - 1
                    await asyncio.sleep(1)
                event.set()
            await asyncio.sleep(1)
        print("Other task running")
        await asyncio.sleep(1)
    
    async def main():
        print_val = asyncio.create_task(start_tic_tock(True))
        await asyncio.gather(other_task(), print_val)
    
    loop.run_until_complete(main())
    

    以上打印:

    Print val is now false
    In new count
    In new count
    In new count
    In new count
    In new count
    tic-tock
    tic-tock
    tic-tock
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多