簡體   English   中英

如何並行使用 asyncio.open_connection 中的讀取器、寫入器?

[英]How to use reader, writer from asyncio.open_connection in parallel?

如何從asyncio.open_connection提供的異步reader, writer對並行讀取和寫入?

我在 2 個不同的循環上嘗試asyncio.open_connection ,例如:

async def read():
    reader, writer = await asyncio.open_connection('127.0.0.1', 5454)
    while True:
        readval = await reader.readline()
        print(f"read {readval}")

async def write():
    reader, writer = await asyncio.open_connection('127.0.0.1', 5454)
    while True:
        self.wsem.acquire()
        msg = self.wq.popleft()
        print("Writing " + msg)
        writer.write(msg.encode())
        await writer.drain()


threading.Thread(target=lambda: asyncio.run(write())).start()
threading.Thread(target=lambda: asyncio.run(read())).start()

但似乎有時寫入線程會耗盡讀取線程中的讀取內容並且效果不佳。

然后我嘗試在兩個循環之間共享讀者、作者,但它拋出異常

Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\threading.py", line 954, in _bootstrap_inner
    self.run()
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Lenovo\PycharmProjects\testape-adb-adapter\adapter\device_socket.py", line 89, in <lambda>
    threading.Thread(target=lambda: asyncio.run(read())).start()
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
    return future.result()
  File "C:\Users\Lenovo\PycharmProjects\testape-adb-adapter\adapter\device_socket.py", line 72, in read
    readval = await self.reader.readline()
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\streams.py", line 540, in readline
    line = await self.readuntil(sep)
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\streams.py", line 632, in readuntil
    await self._wait_for_data('readuntil')
  File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\streams.py", line 517, in _wait_for_data
    await self._waiter
RuntimeError: Task <Task pending name='Task-2' coro=<DeviceSocket.connect.<locals>.read() running at C:\Users\Lenovo\PycharmProjects\testape-adb-adapter\adapter\device_socket.py:72> cb=[_run_until_complete_cb() at C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py:184]> got Future <Future pending> attached to a different loop
async def read():
    connection_opened.wait()
    while True:
        print(f"reading")
        if self.reader.at_eof():
            continue
        readval = await self.reader.readline()
        print(f"read {readval}")
        self.rq.append(readval.decode())
        self.rsem.release(1)

async def write():
    self.reader, self.writer = await asyncio.open_connection('127.0.0.1', 5454)
    connection_opened.set()
    while True:
        self.wsem.acquire()
        msg = self.wq.popleft()
        print("Writing " + msg)
        self.writer.write(msg.encode())
        await self.writer.drain()

connection_opened = threading.Event()
threading.Thread(target=lambda: asyncio.run(write())).start()
threading.Thread(target=lambda: asyncio.run(read())).start()

我認為這應該是一個簡單且相當常見的用例。 這樣做的正確方法是什么?

我建議你把線程函數改成這樣:

t = self.loop.create_task(self.write)

並以:

loop.run_until_complete(t)

因為我缺少self.wqself.wsem function 並且不確定它們的含義,所以我無法重現錯誤消息。 希望這可以為您解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM