python隐藏启动台_如何在Python中启动后台进程?

如何在Python中启动后台进程?

我正在尝试将shell脚本移植到更易读的python版本。 原始shell脚本在后台使用“&”启动多个进程(实用程序,监视器等)。 如何在python中实现相同的效果? 我希望这些进程不会在python脚本完成时死掉。 我确信它与守护进程的概念有某种关系,但我无法轻易找到如何做到这一点。

Artem asked 2019-03-01T10:26:16Z

6个解决方案

299 votes

虽然jkp的解决方案有效,但更新的处理方式(以及文档推荐的方式)是使用subprocess.Popen()模块。 对于简单的命令,它是等价的,但是如果你想做一些复杂的事情,它会提供更多选项。

案例示例:

import subprocess

subprocess.Popen(["rm","-r","some.file"])

这应该在后台运行subprocess.Popen()。 但要小心:subprocess.Popen()只在后台运行进程,如果python脚本中没有任何内容依赖于正在运行的命令的输出:

例如,以下命令不会在后台运行:

import subprocess

ls_output=subprocess.Popen(["ls", "-a"], stdout=subprocess.PIPE)

请参阅此处的文档。

另外,澄清一点:“背景”纯粹是一个shell概念:你可能想要的是产生一个新的过程。 我在这里使用“背景”来引用类似shell的背景行为,但是不要将其误认为实际存在于后台的进程。

Dan answered 2019-03-01T10:28:12Z

65 votes

注意:此答案比2009年发布时的答案要少。现在,在文档中建议使用其他答案中显示的os.P_NOWAIT模块

(请注意,子进程模块提供了更强大的工具来生成新进程并检索其结果;使用该模块比使用这些函数更好。)

如果您希望您的进程在后台启动,您可以使用os.P_NOWAIT并以与shell脚本相同的方式调用它,或者您可以使用spawn:

import os

os.spawnl(os.P_DETACH, 'some_long_running_command')

(或者,您可以尝试使用较不便携的os.P_NOWAIT标志)。

请参阅此处的文档。

jkp answered 2019-03-01T10:26:57Z

32 votes

您可能想要“如何在Python中调用外部命令”的答案。

最简单的方法是使用system函数,例如:

import os

os.system("some_command &")

基本上,无论您传递给system函数的任何内容都将执行,就像您在脚本中将其传递给shell一样。

Eli Courtwright answered 2019-03-01T10:28:54Z

23 votes

我在这里找到了这个:

在Windows(win xp)上,父进程将无法完成,直到DETACHED_PROCESS完成其工作。 这不是你想要的CGI脚本。 问题不是Python特有的,在PHP社区中问题是一样的。

解决方案是将DETACHED_PROCESS进程创建标志传递给win API中的基础CreateProcess函数。 如果你碰巧安装了pywin32,你可以从win32process模块导入标志,否则你应该自己定义:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],

creationflags=DETACHED_PROCESS).pid

f p answered 2019-03-01T10:29:43Z

15 votes

使用subprocess.Popen()和close_fds=True参数,这将允许生成的子进程与Python进程本身分离,并在Python退出后继续运行。

[https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f]

import os, time, sys, subprocess

if len(sys.argv) == 2:

time.sleep(5)

print 'track end'

if sys.platform == 'darwin':

subprocess.Popen(['say', 'hello'])

else:

print 'main begin'

subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)

print 'main end'

Jimmy Yin answered 2019-03-01T10:30:25Z

11 votes

您可能希望开始调查os模块以分叉不同的线程(通过打开交互式会话并发出帮助(os))。 相关函数是fork和任何exec函数。 为了让你了解如何启动,在执行fork的函数中放入这样的东西(函数需要将列表或元组'args'作为包含程序名称及其参数的参数;您可能还需要 为新线程定义stdin,out和err):

try:

pid = os.fork()

except OSError, e:

## some debug output

sys.exit(1)

if pid == 0:

## eventually use os.putenv(..) to set environment variables

## os.execv strips of args[0] for the arguments

os.execv(args[0], args)

Gerald Senarclens de Grancy answered 2019-03-01T10:30:53Z

你可能感兴趣的:(python隐藏启动台)