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

Posted

技术标签:

【中文标题】我正在使用 asyncio,但异步函数正在使用 await asyncio.sleep(5) 阻塞其他异步函数【英文标题】:I'm using asyncio but async function is blocking other async functions with await asyncio.sleep(5) 【发布时间】:2019-06-22 08:28:44 【问题描述】:

我已经在我的库 twbotlib (https://github.com/truedl/twbotlib) 中包含 asyncio 来异步我的代码。

我在一些版本之前尝试了异步命令并且一切顺利,但我不检查是否真的是异步的。然后我尝试创建一个赠品命令并使用await asyncio.sleep(5)。我意识到这会阻止我所有其他代码...

在多次尝试使用 asyncio 代码后,我没有达到结果是在没有阻塞的情况下运行...

(我在main.py中的类Bot有一个名为self.loop的属性,实际上是asyncio.get_event_loop)

我不知道我是否都正确,因为我只是在调用 Run 函数之后,我用 await 调用了所有后续操作。

我尝试将等待替换为 等待 self.loop.create_task(foo)。 我试着做 等待 self.loop.ensure_future(foo) 但什么都没有......

我也尝试将代码拆分为两个函数(mainloop 和 check_data)。

代码中首先是Run函数,这里我开始循环(只是创建任务和run_forever):

    def run(self, startup_function=None) -> None:
        """ Run the bot and start the main while. """

        self.loop.create_task(self.mainloop(startup_function))
        self.loop.run_forever()

其次是mainloop函数(所有的await函数都阻塞了……):

    async def mainloop(self, startup_function) -> None:
        """ The main loop that reads and process the incoming data. """

        if startup_function:
            await startup_function()

        self.is_running = True
        while self.is_running:
            data = self.sock.recv(self.buffer).decode('utf-8').split('\n')
            await self.check_data(data)

最后一个是 check_data(被拆分的 mainloop [为了便于阅读,我已将长 if 替换为“条件”],这里的 await 也是阻塞的):

    async def check_data(self, data: str) -> None:
        for line in data:
            if confition:
                message = self.get_message_object_from_str(line)
                if condition:
                    if condition:
                        await self.commands[message.command](message, message.args)
                    else:
                        await self.commands[message.command](message)
                elif hasattr(self.event, 'on_message'):
                    await self.event.on_message(message)
            if self.logs:
                print(line)

没有错误信息。 代码被阻塞,我正在尝试将其更改为不阻塞代码。

【问题讨论】:

【参考方案1】:

循环for line in data: 阻塞了你的代码。

【讨论】:

以上是关于我正在使用 asyncio,但异步函数正在使用 await asyncio.sleep(5) 阻塞其他异步函数的主要内容,如果未能解决你的问题,请参考以下文章

Django中的异步

在Python中使用asyncio进行异步编程

如何使用 asyncio 和 aiohttp 异步通过 api 响应进行分页

如何使用 asyncio 在 Python 3 中异步运行 requests.get?

如何在库函数中使用异步事件循环

从作为异步任务运行的函数中获取值