等待 asyncio.sleep(1) 在 python 中不起作用

Posted

技术标签:

【中文标题】等待 asyncio.sleep(1) 在 python 中不起作用【英文标题】:await asyncio.sleep(1) not working in python 【发布时间】:2021-09-20 10:20:35 【问题描述】:

我的代码执行没有到达打印语句:print("I want to display after MyClass has started")

这是为什么?我认为 await asyncio.sleep() 的目的是取消阻止代码的执行,以便后续代码行可以运行。不是这样吗?

import asyncio

class MyClass:
    def __init__(self):
        self.input = False
        asyncio.run(self.start())
        
        print("I want to display after MyClass has started")  #This line is never reached.
        
        
    async def start(self):
        while True:
            print("Changing state...")
            if self.input:
                print("I am on.")
                break
            await asyncio.sleep(1)

m = MyClass()
m.input = True  #This line is never reached!  Why?
print("I want to display after MyClass is started")

当我执行时,它会一直打印“正在更改状态...”。即使当我 ctrl+c 退出时,执行也会继续,如下所示。如何正确终止执行?抱歉,我是 python 新手。

编辑: 我很欣赏 asyncio 的常见用途是异步运行两个或多个单独的函数。但是,我的班级将对其状态的变化做出反应。例如,我打算在设置器中编写代码以在类对象属性更改时执行某些操作-同时在后台运行 while True 事件循环。有没有办法允许这样做?我试过在它自己的线程中运行事件循环。但是,该线程随后占主导地位,并且类对象响应时间长达几秒钟。这可能是由于我们无能为力的 GIL(全局解释器锁)。我也尝试过使用多处理,但是当并行进程在它们自己的内存空间中运行时,我无法访问对象的属性和方法。

【问题讨论】:

【参考方案1】:

在 MyClass 的 init 方法中调用 asyncio.run() - 此方法将执行所需的例程,直到该例程终止。在您的情况下,由于 main 方法包含一个 while True 循环,因此它永远不会终止。

这是对您的代码的轻微修改,可能显示了您所追求的并发效果 -

import asyncio
class MyClass:
def __init__(self):
    self.input = False
    asyncio.run(self.main())

    print("I want to display after MyClass has been initialized.")  # This line is never reached.

async def main(self):
    work1 = self.work1()
    work2 = self.work2()
    await asyncio.gather(work1, work2)

async def work1(self):
    for idx in range(5):
        print('doing some work 1...')
        await asyncio.sleep(1)

async def work2(self):
    for idx in range(5):
        print('doing some work 2...')
        await asyncio.sleep(1)
m = MyClass()
print("I want to display after MyClass is terminated")

【讨论】:

谢谢阿隆,在问了我的问题后不久,我想出了一个与你类似的解决方案,它似乎有效;虽然我不明白发生了什么。我创建了两个函数,比如你的 work1() 和 work2()。除了我使用 await asyncio.wait([ asyncio.create_task(work1()), asyncio.create_task(work2()), ]) 调用它们之外,你和我的有什么区别?调用 await asyncio.gather(work1, work2) 和 await asyncio.wait(.....) 有什么区别? Hey Iqbal,asyncio.wait 和 asyncio.gather 相似但有些不同——您应该在***.com/questions/42231161/… 处查看答案以了解具体情况。总体而言,asyncio.wait 更底层,允许细粒度控制。

以上是关于等待 asyncio.sleep(1) 在 python 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

即使使用 asyncio 和 aiohttp,方法也会等待请求响应

我正在使用 asyncio,但异步函数正在使用 await asyncio.sleep(5) 阻塞其他异步函数

RuntimeWarning:启用 tracemalloc 以使用 asyncio.sleep 获取对象分配回溯

如何取消 discord.py 中的 asyncio.sleep 命令

如何使python等待对象

Django — async_to_sync 与 asyncio.run