如何在通常使用Python编写文件的外部进程之间交换大型二进制数据(~50MB)

如何在通常使用Python编写文件的外部进程之间交换大型二进制数据(~50MB),python,unix,pipe,popen,named-pipes,Python,Unix,Pipe,Popen,Named Pipes,我的最终目标是能够在不接触磁盘的情况下通过管道将处理文件的命令行进程连接在一起。这可能吗?我不能使用stdin/stdout,因为我需要运行的某些进程只将文件(有时不止一个)作为输入。我已经成功地使用FIFOs和Popen在Python中处理了小文件,但没有处理更大的文件(以MB为单位)。下面是我用来测试此功能的代码片段 fifo1 = os.getcwd()+'/fifo1.nii' fifo2 = os.getcwd()+'/fifo2.nii' command = 'diff \''+f

我的最终目标是能够在不接触磁盘的情况下通过管道将处理文件的命令行进程连接在一起。这可能吗?我不能使用stdin/stdout,因为我需要运行的某些进程只将文件(有时不止一个)作为输入。我已经成功地使用FIFOs和Popen在Python中处理了小文件,但没有处理更大的文件(以MB为单位)。下面是我用来测试此功能的代码片段

fifo1 = os.getcwd()+'/fifo1.nii'
fifo2 = os.getcwd()+'/fifo2.nii'

command = 'diff \''+fifo1+'\' \''+fifo2+'\''

os.mkfifo(fifo1)
os.mkfifo(fifo2)

with open('1_brain.nii', 'rb', 0) as r:
    s1 = r.read()
with open('run1.nii', 'rb', 0) as r:
    s2 = r.read()

def write(fifo, s):
    with open(fifo, 'wb', 0) as f:
        f.write(s)

writer1 = Thread(target=write, args=[fifo1, s1])
writer1.start()

writer2 = Thread(target=write, args=[fifo2, s2])
writer2.start()

proc = Popen(shlex.split(command), stdout=PIPE)

try:
    while proc.poll() == None:
        continue
    print proc.communicate()[0]
except:
    if proc.poll() == None:
        proc.kill()
    os.unlink(fifo1)
    os.unlink(fifo2)
    raise

os.unlink(fifo1)
os.unlink(fifo2)

这适用于小的文本文件,但是当我在大的二进制文件上运行它时,我在写入线程上得到了一个断管错误,所以看起来读端(diff进程)在写入完成之前就关闭了。我已经让文件读取进程通过使用stdin文件描述符的符号链接来读取stdin,但是我不能使用stdin,因为我有时需要多个输入。有没有办法让FIFO工作,或者可以创建我自己的文件描述符,像stdin一样将数据发送到进程中?如果有任何不清楚的地方,请告诉我!谢谢。

请参阅(1)上的pdf。对于能够运行CPython的计算机来说,50MB不是很大。这表明代码中存在错误(2)为什么将文件读入内存只是为了将它们转储到命名管道中,而不是直接将文件传递给子进程?当proc.poll()==None循环时,创建一(3)个Drop-fagus
,只使用
proc.communicate()
。(4) 无关:你可能有关联:我尝试了5GB输入的变体(比你的案例大100倍)。很好,谢谢你的回复!为了解决您的问题,我将转储到命名管道中,因为我的最终目标是将多个进程链接在一起,所以我的想法是一个进程将转储到管道中,下一个进程将读取它。/dev/fd/文件描述符是否会像管道一样工作,在这方面,它们是否能够实现我刚才描述的行为(从一个进程转储,然后在下一个进程中读取)?参见(1)50MB的pdf对于能够运行CPython的计算机来说不是很大。这表明代码中存在错误(2)为什么将文件读入内存只是为了将它们转储到命名管道中,而不是直接将文件传递给子进程?当proc.poll()==None
循环时,创建一(3)个Drop-fagus
,只使用
proc.communicate()
。(4) 无关:你可能有关联:我尝试了5GB输入的变体(比你的案例大100倍)。很好,谢谢你的回复!为了解决您的问题,我将转储到命名管道中,因为我的最终目标是将多个进程链接在一起,所以我的想法是一个进程将转储到管道中,下一个进程将读取它。/dev/fd/文件描述符是否会像管道一样工作,在这方面,它们是否能够实现我刚才描述的行为(从一个进程转储,然后在下一个进程中读取)?