无法理解 Future.set_result 在另一个线程中的期货行为

Pus*_*kar 3 python python-asyncio

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

asyncio.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
Run Code Online (Sandbox Code Playgroud)

read上面的函数读取可能与wait.

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

    t1 = asyncio.create_task(random_reader.wait(3))
    print(await t1)
Run Code Online (Sandbox Code Playgroud)

我希望在像对象文档这样的函数中self.futures[k].set_result(v)赋值,但是 await 并没有真正执行。尽管期货的状态确实更改为.awaitFutureself.futures"FINISHED"

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

use*_*342 5

Asyncio 期货不是线程安全的- 也不是任何其他 asyncio API,除非另有明确说明。要将未来标记为来自不同线程的完成,请使用call_soon_threadsafe

self.loop.call_soon_threadsafe(self.futures[k].set_result, v)
Run Code Online (Sandbox Code Playgroud)

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

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