从python生成进程
我正在从web应用程序生成一个长时间运行的脚本,如下所示:从python生成进程,python,process,spawn,Python,Process,Spawn,我正在从web应用程序生成一个长时间运行的脚本,如下所示: os.spawnle(os.P_NOWAIT, "../bin/producenotify.py", "producenotify.py", "xx",os.environ) 脚本已成功生成并运行,但在完成之前,我无法释放web应用程序使用的端口,或者换句话说,我无法重新启动web应用程序。如何生成一个进程,并使其完全独立于web应用程序 这是在linux操作系统上。正如@mark澄清的那样,它是一个linux系统,通过遵循这一点,脚
os.spawnle(os.P_NOWAIT, "../bin/producenotify.py", "producenotify.py", "xx",os.environ)
脚本已成功生成并运行,但在完成之前,我无法释放web应用程序使用的端口,或者换句话说,我无法重新启动web应用程序。如何生成一个进程,并使其完全独立于web应用程序
这是在linux操作系统上。正如@mark澄清的那样,它是一个linux系统,通过遵循这一点,脚本可以很容易地使自己完全独立,即成为一个守护进程。(您也可以在
os.fork
之后在父进程中执行,只有在os.exec…
子进程之后)
编辑:为了澄清一些细节,wrt@mark对我的回答发表了评论:按照烹饪书食谱“后台监控”流程不需要超级用户权限,也不需要更改当前工作目录(虽然配方中的代码可以做到这一点,而且还可以做更多,但这不是关键部分——而是fork
、\u exit
和setId
调用的正确逻辑顺序)。各种os.exec…
变体(不以e
结尾)使用父进程的环境,因此该部分也很简单--请参阅
针对其他人的评论和回答中提出的建议:我认为子流程
和多处理
本身并不会对子流程进行后台监控,这似乎是@mark所需要的;脚本可以自己完成,但由于一些代码必须执行fork
和setid
,因此我觉得这样做更整洁在操作过程中,将所有生成代码保留在该低级平面上,而不是混合使用一些高级代码和一些低级代码
在上面的URL中有一个大大简化的配方版本,可以在父级中调用以生成守护程序子级——这样,代码也可以用于执行非Python可执行文件。正如所给出的,代码应该满足@mark explained的需要,当然可以通过许多方式进行定制——我强烈推荐r阅读原始配方及其评论和讨论,以及推荐的书籍,了解更多信息
import os
import sys
def spawnDaemon(path_to_executable, *args)
"""Spawn a completely detached subprocess (i.e., a daemon).
E.g. for mark:
spawnDaemon("../bin/producenotify.py", "producenotify.py", "xx")
"""
# fork the first time (to make a non-session-leader child process)
try:
pid = os.fork()
except OSError, e:
raise RuntimeError("1st fork failed: %s [%d]" % (e.strerror, e.errno))
if pid != 0:
# parent (calling) process is all done
return
# detach from controlling terminal (to make child a session-leader)
os.setsid()
try:
pid = os.fork()
except OSError, e:
raise RuntimeError("2nd fork failed: %s [%d]" % (e.strerror, e.errno))
raise Exception, "%s [%d]" % (e.strerror, e.errno)
if pid != 0:
# child process is all done
os._exit(0)
# grandchild process now non-session-leader, detached from parent
# grandchild process must now close all open files
try:
maxfd = os.sysconf("SC_OPEN_MAX")
except (AttributeError, ValueError):
maxfd = 1024
for fd in range(maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
# redirect stdin, stdout and stderr to /dev/null
os.open(os.devnull, os.O_RDWR) # standard input (0)
os.dup2(0, 1)
os.dup2(0, 2)
# and finally let's execute the executable for the daemon!
try:
os.execv(path_to_executable, args)
except Exception, e:
# oops, we're cut off from the world, let's just give up
os._exit(255)
您可以使用多处理库生成进程。此处显示了一个基本示例:
from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
alex,这是一个类似unix的系统。fedora linux。web应用程序没有超级用户权限。这是一个问题吗?而且守护程序应该与web应用程序具有相同的工作目录和环境变量。我如何实现这些?感谢德克萨斯州的Salex提供澄清。我检查了配方,有点混乱。父web应用程序中的代码是a吗pp?还是它会出现在即将生成的新脚本中?再次感谢!我可以在函数末尾将守护进程pid返回给函数调用方吗?为什么会有两个连续的raise语句?我一直认为第二个语句永远不会执行。在我的应用程序中,第一个孩子会变成带有Alex代码的僵尸。在e“return”,我插入了
os.waitpid(pid,0)
,这对我很有效。但如果有人能证实这一点,我将不胜感激。为什么你不使用subprocess.Popen来做这件事呢?S.洛特:在完成subprocess.Popen之后,我能杀死/重新启动web应用程序/父进程吗?谢谢这有一个问题,即在子进程完成之前不能杀死主进程。谢谢处理库已添加到Python 2.6中。下面是文档@mark如果您希望主进程立即终止而不等待子进程,只需将子进程标记为守护进程。@CadentOrange“此外,这些不是Unix守护进程或服务,它们是将被终止的正常进程(未加入)如果非守护进程已退出。”(文档)不是说在这种情况下守护进程将被终止吗?我不是这么说的吗?如果将子进程标记为守护进程,则如果父进程(即非守护进程)终止,子进程将立即终止。