异步Python - 使用命名管道与子进程进行双向通信

问题描述 投票:0回答:1

有一个关于使用命名管道从子进程读取和写入数据的问题。

我有一个

pygls
语言服务器作为我的主程序的子进程运行。

if not os.path.exists(fifo_in_name):
    os.mkfifo(fifo_in_name)
if not os.path.exists(fifo_out_name):
    os.mkfifo(fifo_out_name)
try:
  fifo_in = os.open(fifo_in_name, os.O_RDONLY | os.O_NONBLOCK)
  fifo_out = os.open(fifo_out_name, os.O_WRONLY | os.O_NONBLOCK)
except OSError as e:
  logger.error(f"Failed to open FIFO: {e}")
  raise e


process = await asyncio.create_subprocess_exec(
    sys.executable, 'lsp/lsp_server.py', fifo_in_name, fifo_out_name,
)

在我的 lsp_server.py 中,我像这样启动我的服务器:

@contextmanager
def open_fifo(name, mode):
    fd = os.open(name, mode | os.O_NONBLOCK)
    try:
        if mode & os.O_RDONLY:
            file_obj = os.fdopen(fd, 'rb', buffering=0)
        elif mode & os.O_WRONLY:
            file_obj = os.fdopen(fd, 'wb', buffering=0)
        else:
            raise ValueError("Unsupported mode")
        yield file_obj
    finally:
        file_obj.close()


if __name__ == "__main__":
    fifo_in = sys.argv[1]
    fifo_out = sys.argv[2]
    with open_fifo(fifo_in, os.O_RDONLY) as f, open_fifo(fifo_out, os.O_WRONLY) as r:
        server.start_io(f, r)
        print("Started LSP server")

尝试从主程序打开

OSError: [Errno 6] Device not configured: '/tmp/fifo_out'
时,我收到
fifo_out
。我将不胜感激有关正确使用管道进行双向通信的一些指导。

python python-asyncio
1个回答
0
投票

要解决尝试从主程序打开

“OSError: [Errno 6]
时出现的“
fifo_out
设备未配置”问题,请考虑使用匿名管道而不是命名管道 (FIFO)。匿名管道是在创建子进程时由操作系统自动设置的。修改您的代码以使用匿名管道,并确保您的子进程 (
lsp_server.py
) 正确读取和写入其标准输入和输出流。这种方法简化了通信并避免了显式管道配置的需要。

示例:

import asyncio
import sys
from multiprocessing import Pipe

def child_process(pipe):
    pass

if __name__ == "__main__":
    parent_conn, child_conn = Pipe(duplex=True)
    process = await asyncio.create_subprocess_exec(
        sys.executable, 'lsp/lsp_server.py', stdin=child_conn, stdout=child_conn
    )

    parent_conn.close()
    child_conn.close()
© www.soinside.com 2019 - 2024. All rights reserved.