当前位置:  开发笔记 > 编程语言 > 正文

确保子程序在退出Python程序时已经死了

如何解决《确保子程序在退出Python程序时已经死了》经验,为你挑选了3个好方法。

有没有办法确保所有创建的子进程在Python程序的退出时间都死了?通过子进程,我指的是使用subprocess.Popen()创建的.

如果没有,我应该迭代所有发出的杀戮然后杀死-9?什么更干净?



1> monkut..:

您可以使用atexit,并注册在程序退出时要运行的任何清理任务.

atexit.register(func [,*args [,**kargs]])

在清理过程中,您还可以实现自己的等待,并在发生所需的超时时将其终止.

>>> import atexit
>>> import sys
>>> import time
>>> 
>>> 
>>>
>>> def cleanup():
...     timeout_sec = 5
...     for p in all_processes: # list of your processes
...         p_sec = 0
...         for second in range(timeout_sec):
...             if p.poll() == None:
...                 time.sleep(1)
...                 p_sec += 1
...         if p_sec >= timeout_sec:
...             p.kill() # supported from python 2.6
...     print 'cleaned up!'
...
>>>
>>> atexit.register(cleanup)
>>>
>>> sys.exit()
cleaned up!

- 如果此进程(父进程)被终止,则不会运行已注册的函数.

python> = 2.6不再需要以下windows方法

这是一种在Windows中杀死进程的方法.你的Popen对象有一个pid属性,所以你可以通过success = win_kill(p.pid)调用它(需要安装pywin32):

    def win_kill(pid):
        '''kill a process by specified PID in windows'''
        import win32api
        import win32con

        hProc = None
        try:
            hProc = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, pid)
            win32api.TerminateProcess(hProc, 0)
        except Exception:
            return False
        finally:
            if hProc != None:
                hProc.Close()

        return True



2> orip..:

在*nix上,也许使用进程组可以帮助你 - 你也可以捕获子进程产生的子进程.

if __name__ == "__main__":
  os.setpgrp() # create new process group, become its leader
  try:
    # some code
  finally:
    os.killpg(0, signal.SIGKILL) # kill all processes in my group

另一个考虑因素是升级信号:从SIGTERM(默认信号kill)到SIGKILL(aka kill -9).在信号之间等待一会儿,让过程有机会在你之前干净地退出kill -9.



3> S.Lott..:

subprocess.Popen.wait()是确保他们死亡的唯一方法.实际上,POSIX OS要求您等待您的孩子.许多*nix将创建一个"僵尸"过程:一个死孩子,父母没有等待.

如果孩子写得合理,它就会终止.孩子们常常从PIPE上读到.关闭输入是一个很大的暗示,孩子应该关闭购物和退出.

如果孩子有虫子并且没有终止,你可能不得不杀死它.你应该修复这个bug.

如果孩子是"永远服务"循环,并且不是为了终止,你应该杀死它或者提供一些输入或消息来强制它终止.


编辑.

在标准操作系统中,你有os.kill( PID, 9 ).Kill -9很苛刻,BTW.如果你能用SIGABRT(6?)或SIGTERM(15)杀死它们,那就更有礼貌了.

在Windows操作系统中,您没有os.kill可行的功能.查看此ActiveState配方以终止Windows中的进程.

我们有子进程是WSGI服务器.要终止它们,我们在特殊URL上进行GET; 这导致孩子清理并退出.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有