Python3.6 cocotb协程:在同步函数中调用包含”yield“的异步函数

Python3.6 cocotb coroutine: calling asynchronous function containing ”yield“ in synchronous function

我在尝试制作一个调用异步函数的同步函数时遇到了一些问题。(python 3.6.9,cocotb 1.4.0)

如下例代码所示。 read_cb 函数将调用 read 函数(在 FakeDriver class 中)。

在运行之后,我得到了错误

yield self._fake_lock()
RuntimeError: Task got bad yield: <cocotb.decorators.RunningCoroutine object at 0x7f7fecdbfe10>

我要的是

init FakerDriver
locking... 
locking done
read...
addr: 0x01 
unlocking... 
unlocking done
read done
import cocotb
import asyncio
from cocotb.decorators import coroutine
from cocotb.triggers import Event

class FakeDriver():
    def __init__(self):
        print("init FakeDriver")
        self.busy_event = Event("driver_busy")
        self.busy = False

    @coroutine
    def read(self, addr):
        print("read...")

        yield self._fake_lock()
        print("addr: ", addr)
        self._fake_unlock()

        print("read done")

    @coroutine
    def _fake_lock(self):
        print("locking...")
        if self.busy:
            yield self.busy_event.wait()

        self.busy_event.clear()
        self.busy = True
        print("locking done")

    def _fake_unlock(self):
        print("unlocking...")
        self.busy = False
        self.busy_event.set()
        print("unlocking done")

def read_cb():
    dri = FakeDriver()
    loop = asyncio.get_event_loop()
    task = loop.create_task(dri.read("0x01"))
    ret = loop.run_until_complete(task)
    loop.close()

if __name__ == "__main__":
    read_cb()

不要混淆 cocotb 自己的协程实现和 asyncio 的实现。 在您的情况下,完全摆脱 asyncio 导入,并使用旧的 cocotb 1.4.0,使用 cocotb 的 fork() 而不是 create_task()(如 https://docs.cocotb.org/en/v1.4.0/quickstart.html?highlight=fork#parallel-and-sequential-execution 中所述)。

在使用 cocotb 中已弃用的 yield 等创建大量新代码之前,请考虑将 cocotb 升级到 1.6.1 并使用 async def/await(同样来自 cocotb,而不是 asyncio),而不是 fork(),使用 start_soon()(参见 https://docs.cocotb.org/en/v1.6.1/coroutines.html#concurrent-execution and https://www.fossi-foundation.org/2021/10/20/cocotb-1-6-0)。

(我现在看到你也在https://github.com/cocotb/cocotb/issues/2819问过这个)