python - 无法理解另一个线程中 future.set_result 的行为

标签 python python-asyncio

我想要一个类函数暂停执行,直到另一个线程按照该函数的请求更改类变量的值。我是 python asyncio 模块的新手。

asyncio.Future 似乎提供了一种等待 future 值的机制,因此我尝试按照一个玩具示例进行操作:

class RandomReader:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.service = 3
        self.thread = threading.Thread(target=self.reader)
        self.thread.start()
        self.futures: Dict[int, asyncio.Future] = {}

    def reader(self):
        asyncio.set_event_loop(self.loop)
        while self.service != 0:
            k, v = read()
            if k in self.futures:
                if self.futures[k].done():
                    continue

                self.futures[k].set_result(v)
                self.service -= 1

    async def wait(self, v: int):
        self.futures[v] = self.loop.create_future()
        a = await self.futures[v]
        logging.debug("value %d received %f", v, a)
        return v, a

read上面的函数读取可能与 wait 匹配的随机键和值.

调用函数进行如下调用 3 次 ( RandomReader.service )

    t1 = asyncio.create_task(random_reader.wait(3))
    print(await t1)

我预计self.futures[k].set_result(v)将值赋给 await功能类似于 documentationFuture对象,但等待实际上并没有执行。尽管 future 状况self.futures确实更改为 "FINISHED" .

非常感谢您对此的任何帮助。

最佳答案

Asyncio futures 不是线程安全的 - 任何其他 asyncio API 也不是,除了 explicitly noted otherwise 。要将 future 标记为从不同线程完成,请使用 call_soon_threadsafe :

self.loop.call_soon_threadsafe(self.futures[k].set_result, v)

该调用将通知事件循环正在发生某些事情,并使事件循环设置 future 的结果,立即注意到它并唤醒等待的协程。

另请注意,reader() 中对 asyncio.set_event_loop() 的调用看起来不正确,因为事件循环实际上 在读者线程中运行。

关于python - 无法理解另一个线程中 future.set_result 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57144657/

相关文章:

Python 异步强制超时

python - 从 async.subprocess.PIPE 读取

python - AWS lambda 与 python asyncio。事件循环关闭问题?

python - 如何在Python中截取stdout的内容?

python - 根据其他值向字典添加值

python - 从多项式回归(图)获取函数 ("f(x)")

python - 是否有不生成列表的 python 3 for 循环单行代码?

python - 为什么 numpy 让你添加不同大小的数组?

python - 如何在pytest中为asyncio代码编写fixture

python - FastAPI 中音频流的 Websockets 桥接器