
如果您查看的来源
subprocess.communicate(),则显示了差异的完美示例:
def communicate(self, input=None): ... # Optimization: If we are only using one pipe, or no pipe at # all, using select() or threads is unnecessary. if [self.stdin, self.stdout, self.stderr].count(None) >= 2: stdout = None stderr = None if self.stdin: if input: self.stdin.write(input) self.stdin.close() elif self.stdout: stdout = self.stdout.read() self.stdout.close() elif self.stderr: stderr = self.stderr.read() self.stderr.close() self.wait() return (stdout, stderr) return self._communicate(input)
你可以看到,
communicate确实让使用读取调用来
stdout和
stderr,还呼吁
wait()。这只是 *** 作顺序的问题。在您的情况下,因为您同时使用
PIPE了stdout和stderr,它进入
_communicate():
def _communicate(self, input): stdout = None # Return stderr = None # Return if self.stdout: stdout = [] stdout_thread = threading.Thread(target=self._readerthread, args=(self.stdout, stdout)) stdout_thread.setDaemon(True) stdout_thread.start() if self.stderr: stderr = [] stderr_thread = threading.Thread(target=self._readerthread, args=(self.stderr, stderr)) stderr_thread.setDaemon(True) stderr_thread.start() if self.stdin: if input is not None: self.stdin.write(input) self.stdin.close() if self.stdout: stdout_thread.join() if self.stderr: stderr_thread.join() # All data exchanged. Translate lists into strings. if stdout is not None: stdout = stdout[0] if stderr is not None: stderr = stderr[0] # Translate newlines, if requested. We cannot let the file # object do the translation: It is based on stdio, which is # impossible to combine with select (unless forcing no # buffering). if self.universal_newlines and hasattr(file, 'newlines'): if stdout: stdout = self._translate_newlines(stdout) if stderr: stderr = self._translate_newlines(stderr) self.wait() return (stdout, stderr)
这使用线程一次读取多个流。然后
wait()在最后调用。
总结一下:
- 本示例一次从一个流中读取,并且不等待它完成该过程。
- 本示例通过内部线程同时从两个流中读取,并等待它完成该过程。
- 本示例等待过程完成,然后一次读取一个流。正如您提到的,如果流中写入的内容过多,则有可能导致死锁。
另外,在第二个和第三个示例中,您不需要这两个import语句:
from subprocess import communicatefrom subprocess import wait
它们都是
Popen对象的方法。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)