我有一个关于命名管道或Python中类似的东西的问题,以及它们是否可以为我的用例工作。我有类似下面的代码。
fn = path/to/my/file.ext
os.mkfifo(fn)
subprocess.check_output(args=(bar -o fn).split())
foo(fn)
字符串
我的目标是不将子进程条的输出写入光盘,而是直接将其导入foo()
函数。遗憾的是,foo()
函数只接受文件名,而不接受任何类型的描述符/句柄。因此,我需要定义某种内存文件,它可以被子进程和foo()
函数使用。正如我所理解的,命名管道非常接近我想要的,然而它被设计为只在两端连接时工作,而不是作为内存文件/缓冲区中的某种中间体,因此它已经挂起子进程调用(有可能我做错了/理解错了什么)。命名管道是正确的方法还是我应该使用其他方法?
(另外,我也想避免os.O_NONBLOCK
这样的东西,因为它们只在Linux上工作)foo()
函数仅从文件中读取。
非常感谢任何帮助!
1条答案
按热度按时间2uluyalo1#
命名管道是解决此问题的有效方法。您当前的方法失败,因为
subprocess.check_output
等待进程终止。在排空管道之前,不会发生这种情况。因此,第一个修复方法是调用subprocess.Popen
,并在从管道读取时让进程继续运行。然而,这又带来了一个新问题:
fn
如何知道该过程已完成?通常您会读取到文件结尾(EOF)。当写入端关闭时,管道发出EOF信号。对于命名管道,文件系统中的文件条目是一个写入器(打开管道的子进程算作第二个写入器)。因此,fn
将无限期地等待EOF。您需要做的是在该过程完成后删除命名管道。最简单的方法是使用单独的线程。
字符串
这其中有一个问题:如果进程在
fn
打开管道之前终止,则第二个线程可能会在fn
有机会打开管道之前删除管道。我想如果子流程不创建输出,可能会发生这种情况。该异常应该很容易捕获。“