用Python以非阻塞方式调用外部程序

4

有没有一种方法在Python中调用外部程序而不等待其执行完成?

我尝试了这个方法,但没有成功:

os.system("external_program &")

通常,如果我在bash shell中调用external_program &,它会作为后台进程执行。 我如何在python中做到这一点?对于我的特殊情况,创建另一个线程行不通。在主python脚本完成后,外部程序应该继续执行。

你能并行运行它吗?没有依赖关系吗? - Raphael
2个回答

5

是的,可以使用subprocess模块。例如:

p = subprocess.Popen(['external_program', 'arg1', 'arg2'])
# Process is now running in the background, do other stuff...
...
# Check if process has completed
if p.poll() is not None:
    ...
...
# Wait for process to complete
p.wait()

1
我尝试了这个。它仍然被阻止。如果它起作用,如果我在最后不等待会发生什么?它会被杀掉吗? - Gokhan Ka
我意识到它实际上是有效的,但主脚本在最后等待。我需要完全独立于主脚本。这可能吗? - Gokhan Ka
@GokhanKa:如果您不希望主脚本等待,请不要调用wait()函数,这很简单。如果在子进程仍在运行时退出,则其将在后台继续运行。 - Adam Rosenfield
1
我没有调用wait()。在Popen调用之后,它甚至不执行sys.exit(0)。如果我调用p.terminate(),它会立即终止子进程并退出。这是多么奇怪啊? - Gokhan Ka
来自一个重复的经验,我想强调:用p = subprocess.Popen(['thing'])代替os.system("thing &")(不需要使用&,也不需要使用shell),然后进行任何其他你想要做的操作。因为你创建了一个子进程,所以p将存在并在后台运行,就像shell使用&一样,你可以使用p.wait()最终清除它。如果thing由于写入管道或其他原因而阻塞,情况会变得更加复杂和微妙,但是还有其他问题会详细解释这一点。 - tripleee

2
忘掉os.system()吧,它已经被淘汰了, subprocess模块是更好的选择。它提供了一种执行几乎所有可想用例的子程序的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接