Python:使用subprocess流式传输数据避免死锁?

2 投票
1 回答
571 浏览
提问于 2025-04-16 08:05

我正在写一个小脚本,用来处理很多数据的随机排序。大概是这样的:

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 时,我遇到了死锁的问题(见评论)。

文档中提到的“解决方案”是使用 .communicate()……但是这样做会把所有输入都读到内存里,然后再处理,这样不太好。

那么,我该如何在子进程之间流畅地传输数据,而不出现死锁呢?

1 个回答

0

你没有在子进程实际读取的管道上使用 close,所以它不会收到 SIGPIPE 信号,也不会因此退出。当你有足够的数据时,直接杀掉这个进程就行。另一种方法是同时处理输入和输出,然后用 select 来判断什么时候该读取或写入。

撰写回答