阻塞和非阻塞子进程调用 [英] Blocking and Non Blocking subprocess calls

查看:48
本文介绍了阻塞和非阻塞子进程调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全混淆了 subprocess.call()subprocess.Popen()subprocess.check_call().

I'm completely confused between subprocess.call() , subprocess.Popen(), subprocess.check_call().

哪个是阻塞的,哪个不是?

Which is blocking and which is not ?

我想说的是,如果我使用subprocess.Popen(),父进程是否等待子进程return/exit> 在它继续执行之前.

What I mean to say is if I use subprocess.Popen() whether the parent process waits for the child process to return/exit before it keep on its execution.

shell=True 如何影响这些调用?

推荐答案

Popen 是非阻塞的.callcheck_call 正在阻塞.您可以通过调用 waitcommunicate 方法来制作 Popen 实例块.

Popen is nonblocking. call and check_call are blocking. You can make the Popen instance block by calling its wait or communicate method.

如果您查看源代码,您会看到call 调用 Popen(...).wait(),这就是它阻塞的原因.check_call 调用 call,这也是它阻塞的原因.

If you look in the source code, you'll see call calls Popen(...).wait(), which is why it is blocking. check_call calls call, which is why it blocks as well.

严格来说,shell=True 与阻塞问题是正交的.但是,shell=True 会导致 Python 执行一个 shell,然后在 shell 中运行命令.如果您使用阻塞调用,则该调用将在 shell 完成后返回.由于外壳可能会产生一个子进程来运行命令,外壳可能会在产生的子进程之前完成.例如,

Strictly speaking, shell=True is orthogonal to the issue of blocking. However, shell=True causes Python to exec a shell and then run the command in the shell. If you use a blocking call, the call will return when the shell finishes. Since the shell may spawn a subprocess to run the command, the shell may finish before the spawned subprocess. For example,

import subprocess
import time

proc = subprocess.Popen('ls -lRa /', shell=True)
time.sleep(3)
proc.terminate()
proc.wait()

这里产生了两个进程: Popen 产生了一个运行 shell 的子进程.shell 反过来产生一个运行 ls 的子进程.proc.terminate() 杀死了 shell,但运行 ls 的子进程仍然存在.(这表现为大量输出,即使在 python 脚本结束之后.准备用 pkill ls 杀死 ls.)

Here two processes are spawned: Popen spawns one subprocess running the shell. The shell in turn spawns a subprocess running ls. proc.terminate() kills the shell, but the subprocess running ls remains. (That is manifested by copious output, even after the python script has ended. Be prepared to kill the ls with pkill ls.)

这篇关于阻塞和非阻塞子进程调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆