【问题标题】:Deadlock on communicating with multiple children与多个孩子沟通的僵局
【发布时间】:2015-08-03 16:15:16
【问题描述】:

这是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

为什么即使我关闭了他们的stdin,孩子们仍然继续read()

PS。关闭所有子标准输入从其中任何一个读取之前关闭的简单更改解决问题:

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

为什么?!

【问题讨论】:

  • python parent.py 100 2 每次都为我工作。
  • @Celada:你用的是python 2.7,对吧?
  • 是的,我使用的是 2.7.3。
  • 您的意思是“注意...的简单更改”?
  • @G-Man:是的!已修复,谢谢!

标签: pipe ipc deadlock


【解决方案1】:

这原来是 Python 2.6

中的一个错误

Python 2.7不会死锁。

【讨论】:

  • @Celada: 看起来像,但错误说它不应该在 2.7 中修复 - 我的问题在 2.7 中没有表现出来,所以我不确定。
  • 哦,是的,我误读为 will 向后移植到 2.7 而不是 won't 向后移植到 2.7。所以确实它一定是其他一些错误。
【解决方案2】:

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

【讨论】:

  • 是的,但是父级确实关闭了管道的另一端:你得到了for n,p in children: p.stdin.close()。我和 OP 缺少什么?
  • @Celada 我猜他最初并没有关闭管道并且它陷入了僵局。现在他修好了,他在问为什么关闭管道可以解决死锁。
  • 不,你对我的问题的解释完全不正确,
  • @sds 好的。我的系统存储库中只有 2.7 和 3.*。但如果这是一个 python 错误,那就太奇怪了。 (我的意思是这应该是一些相当直接的 python 代码与系统函数的粘合)。无论如何,我很高兴你明白了。
猜你喜欢
  • 1970-01-01
  • 2011-02-21
  • 2021-04-25
  • 2019-02-04
  • 2019-05-22
  • 1970-01-01
  • 2014-02-16
  • 2011-02-20
  • 2017-07-01
相关资源
最近更新 更多