有一个关于使用命名管道从子进程读取和写入数据的问题。
我有一个
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
。我将不胜感激有关正确使用管道进行双向通信的一些指导。
要解决尝试从主程序打开
“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()