【问题标题】:Asyncio - create_task blocks threadAsyncio - create_task 阻塞线程
【发布时间】:2021-11-10 21:23:33
【问题描述】:

我正在尝试创建一个 Python 脚本,该脚本将从 websocket 连接接收消息,并且每次收到新消息时,它都需要在后台运行 asyncio 任务。

为了“模拟”这个过程,我做了一个阻塞函数,它以while True 语句开始计数。预期的输出是每次从 ws 连接接收到新消息时,都会开始新的计数,但在我的情况下,只要我运行脚本,计数函数就会阻塞整个代码。我该如何解决这个问题?

这是我尝试过的:

import asyncio
import websockets
import json
import time

#this is the blocking function..
def counter():
    count = 0
    while True:
        print(count)
        count += 1
        time.sleep(0.5)
    
async def main():
    while True:
        try:
            async with websockets.connect('MY-URL') as websocket:

                while True:
                    msg = await asyncio.wait_for(websocket.recv(), 500)
                   
                    try:
                        data = json.loads(msg)
                        await loop.create_task(counter())

                    except Exception as e:
                        print(e)
        
        except Exception as e:
            print(e)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

【问题讨论】:

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


    【解决方案1】:

    这里有两个主要问题。您的第一个问题是,您在counter 中创建了一个无限循环,然后在您尝试将其传递给create_task 时调用它。这样create_task 甚至都不会被调用。 第二个明显的问题是,您尝试将一个方法传递给create_task,而它需要一个协程。 使用async def 再次将counter 方法定义为协程,并将time.sleep 替换为asyncio.sleep,我认为它可能会起作用。

    作为一般说明:您不能在与事件循环相同的线程中使用阻塞代码。这意味着永远不要在异步代码中使用time.sleep...

    【讨论】:

      猜你喜欢
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 2020-12-29
      • 2015-12-04
      • 2016-01-27
      • 1970-01-01
      相关资源
      最近更新 更多