Python:使用子流程来流化数据而不产生死锁?

Python:使用子流程来流化数据而不产生死锁?,python,subprocess,Python,Subprocess,我正在写一个小脚本来处理大量数据。是这样的: outproc = None for input in input_files: p = Popen('process_input "%s" | more_input_processing' %(input, ), shell=True, stdout=PIPE) for line in p.stdout.xreadlines(): if linecount % 1000000 == 0:

我正在写一个小脚本来处理大量数据。是这样的:

outproc = None
for input in input_files:
    p = Popen('process_input "%s" | more_input_processing' %(input, ),
              shell=True, stdout=PIPE)
    for line in p.stdout.xreadlines():
        if linecount % 1000000 == 0:
            outfile = "output%03d" %(linecount // 1000000, )
            if outproc:
                outproc.stdin.close()
                result = outproc.wait() # <-- deadlock here
                assert result == 0, "outproc exited with %s" %(result, )
            outproc = Popen('handle_output "%s"' %(outfile, ),
                            shell=True, stdin=PIPE)
        linecount += 1
        outproc.stdin.write(line)
    p.stdout.close()
    result = p.wait()
    assert result == 0, "p exited with %s" %(result, )
不过,正如文档所警告的,当我尝试等待outproc see注释时,我遇到了一个死锁

文档中提出的“解决方案”是使用。通信…但这样做需要在刷新之前将所有输入读取到内存中,这是不可取的


那么,如何在没有死锁的情况下在子流程之间传输数据呢?

您没有在子流程实际读取的管道上使用close,因此它不会接收SIGPIPE或任何导致其退出的内容。当您有足够的数据时,只需停止进程。或者,对输入和输出进行管道连接,并使用select来知道何时应该读取或写入。

您没有在子流程实际读取的管道上使用close,因此它不会接收SIGPIPE或任何导致其退出的内容。当您有足够的数据时,只需停止进程。或者,对输入和输出进行管道连接,并使用select来知道何时应该读取或写入。

您说的“不在子流程读取的管道上使用close”是什么意思?handle_输出脚本不断地从stdin读取数据……因此,当我outproc.stdin.close时,这不是关闭了它从中读取数据的管道吗?子进程的stdin不是进程自己打开的管道;它从命令行args打开了一个文件,您不能代表它关闭它。Hrm。好吧……但是仅仅终止进程也不够好:它希望在完成从stdin的读取后对数据库提交进行一些清理,如果终止,则不会发生。你说的“不在子进程读取的管道上使用close”是什么意思?handle_输出脚本不断地从stdin读取数据……因此,当我outproc.stdin.close时,这不是关闭了它从中读取数据的管道吗?子进程的stdin不是进程自己打开的管道;它从命令行args打开了一个文件,您不能代表它关闭它。Hrm。好吧…但是仅仅终止进程也不够好:它希望在完成从stdin的读取后对数据库进行一些清理,如果终止,则不会发生。好吧,如果我没有真正等待子进程ie,请删除对的所有调用。等等,一切似乎都正常,对于这个脚本来说,这是很好的,它只是一次过的。如果我能弄清楚如何使它正常工作,那就太好了……好吧,如果我不真正等待子进程,也就是说,删除所有对的调用。等等,一切似乎都正常,这对这个脚本来说很好,这只是一次性的。如果我能想出如何使它正常工作,那就太好了,不过…