阻止和非阻止子进程调用

时间:2021-09-26 22:57:44

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

我在subprocess.call(),subprocess.Popen(),subprocess.check_call()之间完全混淆。

Which is blocking and which is not ?

哪个是*哪个不是?

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.

我的意思是说,如果我使用subprocess.Popen(),父进程是否等待子进程在继续执行之前返回/退出。

How does shell=True affect these calls?

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

1 个解决方案

#1


60  

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

Popen是非阻塞的。 call和check_call是阻塞的。您可以通过调用其wait或communic方法来创建Popen实例块。

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.

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

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,

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

import subprocess
import time

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

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.)

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

#1


60  

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

Popen是非阻塞的。 call和check_call是阻塞的。您可以通过调用其wait或communic方法来创建Popen实例块。

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.

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

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,

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

import subprocess
import time

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

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.)

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