Python中Named Pipe或共享内存文件的使用适配咨询
关于Python中命名管道(Named Pipe)适配场景的问题
现有代码如下:
fn = "path/to/my/file.ext" os.mkfifo(fn) subprocess.check_output(args=("bar -o fn").split()) foo(fn)
我的目标是不将子进程bar的输出写入磁盘,而是直接传入foo()函数。但foo()仅接受文件名,不支持文件描述符/句柄。因此我需要一种可被子进程和foo()共同使用的内存文件/缓冲区。我了解Named Pipe接近需求,但它需两端同时连接才能工作,导致子进程调用时出现挂起(可能我的理解或操作有误)。请问Named Pipe是正确方案吗?还是应使用其他方式?
(另外我希望避免os.O_NONBLOCK这类仅Linux可用的机制)
注:foo()仅读取文件。
问题原因
你遇到的挂起是因为命名管道(FIFO)的特性:当只有一端打开时,另一端的读写操作会阻塞。当前代码创建FIFO后直接调用子进程写数据,但此时没有任何进程打开读端,导致子进程卡在写操作上。
解决方案
1. 命名管道+线程(无磁盘写入)
命名管道完全符合你的需求,只需用线程提前打开读端解除阻塞:
import os import subprocess import threading def keep_fifo_open(fn): # 保持FIFO读端打开,避免子进程写操作阻塞 with open(fn, 'r'): pass pipe_path = "interprocess_pipe" try: os.mkfifo(pipe_path) # 启动守护线程提前打开读端 threading.Thread(target=keep_fifo_open, args=(pipe_path,), daemon=True).start() # 执行子进程输出到管道 subprocess.run(["bar", "-o", pipe_path], check=True) # 让foo读取管道内容 foo(pipe_path) finally: # 清理管道文件 os.unlink(pipe_path)
注意:Windows平台不支持os.mkfifo,若需跨平台兼容,可改用win32pipe模块创建Windows专属命名管道,核心逻辑保持一致。
2. 内存临时文件(跨平台,无物理磁盘写入)
如果不想处理线程或跨平台适配问题,可利用内存文件系统创建临时文件,数据不会写入物理磁盘:
import tempfile import os import subprocess # Linux/macOS用/dev/shm(内存挂载目录),Windows直接用系统临时目录 temp_dir = "/dev/shm" if os.name != 'nt' else None with tempfile.NamedTemporaryFile(dir=temp_dir, delete=False) as tmp_file: temp_path = tmp_file.name try: subprocess.run(["bar", "-o", temp_path], check=True) foo(temp_path) finally: os.unlink(temp_path)
这个方案逻辑更简单,无需额外线程,跨平台兼容性更好,小数据量场景下几乎无性能损耗。
内容的提问来源于stack exchange,提问作者N1l5
相关产品推荐
相关产品推荐

