与多个孩子沟通时遇到僵局

时间:2015-08-03 16:15:17

标签: pipe ipc deadlock

这是previous question

的后续内容

我有parent.py

from sys import argv
from random import randrange
from subprocess import Popen, PIPE
lines = int(argv[1])
procs = int(argv[2])
cmd = ["python", "child.py"]
children = list()
for p in range(procs):
  children.append([0,Popen(cmd, stdin=PIPE, stdout=PIPE)])
for i in range(lines):
    child = children[randrange(procs)]
    child[0] += 1
    child[1].stdin.write("hello\n")
for n,p in children:
    p.stdin.close()
    out = p.stdout.read()
    p.stdout.close()
    exitcode = p.wait()
    print n,out,exitcode
    assert n == int(out)
assert lines == sum(n for n,_ in children)

child.py

import sys
l = list()
for line in sys.stdin:
   l.append(line)
sys.stdout.write(str(len(l)))

当我创建一个孩子时,它可以正常工作:

$ python parent.py 100 1
100 100 0

然而,多个孩子陷入僵局:

$ python parent.py 100 2 &
[1] 59492
$ strace -p 59492
Process 59492 attached - interrupt to quit
read(5, ^C <unfinished ...>
Process 59492 detached
$ pstree -p 59492
python(59492)-+-python(59494)
              `-python(59495)
$ strace -p 59494
Process 59494 attached - interrupt to quit
read(0, ^C <unfinished ...>
Process 59494 detached
$ strace -p 59495
Process 59495 attached - interrupt to quit
read(0, ^C <unfinished ...>
Process 59495 detached

为什么即使我关闭read()后孩子仍然stdin

PS。关闭所有孩子的标准 之前的简单更改 解决问题:

$ python parent.py 10000 4
2486 2486 0
2493 2493 0
2531 2531 0
2490 2490 0

为什么?!

2 个答案:

答案 0 :(得分:1)

这是Python 2.6

中的一个错误

Python 2.7 死锁。

答案 1 :(得分:0)

您已经将您的孩子编程为阅读所有标准输入(for line in sys.stdin:),即继续阅读直至达到EOF。如果他们的stdin是管道,当管道的另一端关闭时,它们将获得EOF。