有人可以解释管道缓冲区死锁吗?

Alm*_*mad 10 python operating-system pipe

Popen的Python文档指出:

警告使用communic()而不是.stdin.write,.stdout.read或.stderr.read来避免由于任何其他OS管道缓冲区填满和阻止子进程而导致的死锁.

现在,我试图弄清楚这种僵局是如何发生的以及原因.

我的心理模型:subproccess生成一些stdout/err,它被缓冲,填充缓冲区之后,它被刷新到subproccess的stdout/err,它通过管道发送到父进程.

从文档说明,管道拥有它自己的缓冲区,当它被填充或子进程终止时,它被刷新到父进程.

无论哪种方式(使用管道缓冲区),我都不完全确定死锁是如何发生的.我唯一能想到的是某种"全局"OS管道缓冲进程将会争取,这听起来很奇怪.另一个是更多进程将共享相同的管道,这不应该自己发生.

有人可以解释一下吗?

S.L*_*ott 6

小心,这有一个微妙的错误.

我的心理模型:subproccess生成一些stdout/err,它被缓冲,填充缓冲区之后,它被刷新到subproccess的stdout/err,它通过管道发送到父进程.

缓冲区由父进程和子进程共享.

子进程生成stdout的东西,这是父进程应该从中读取的缓冲区.

填充缓冲区时,写入将停止,直到缓冲区清空为止.Flush对管道没有任何意义,因为两个进程共享同一个缓冲区.

刷新到磁盘意味着设备驱动程序必须将字节向下推送到设备.刷新套接字意味着告诉TCP/IP停止等待累积缓冲区并发送内容.刷新到控制台意味着停止等待换行符并将字节通过设备驱动程序推送到设备.


Wim*_*Wim 5

当两个缓冲区(标准输入和标准输出)都已满时,可能会发生死锁:您的程序正在等待向外部程序写入更多输入,而外部程序正在等待您首先从其输出缓冲区读取。

这可以通过使用非阻塞 I/O 并适当地确定缓冲区的优先级来解决。你可以尝试自己让它工作,但communicate()只是为你做。