如何使用Popen运行背景过程并避免僵尸?

Pol*_*toS 4 python subprocess process zombie-process

我有一个侦听器服务器为每个客户端处理程序运行新线程.每个处理程序可以使用

proc = subprocess.Popen(argv, executable = "./Main.py", stdout = _stdout, stderr = subprocess.STDOUT, close_fds=False)
Run Code Online (Sandbox Code Playgroud)

在处理程序线程结束之后,在后台运行新进程.

后台处理结束后,保持Z状态.是否有可能要求subprocess.Popen()处理SIG_CHILD以避免这个僵尸?

我不想使用proc.wait()读取进程状态,因为为此我要保存所有正在运行的后台进程的列表...

UPD

我需要在后台运行一些进程来避免僵尸,并使用.communicate()运行一些进程来从这些进程中读取数据.在那种情况下使用来自koblas的信号技巧我得到一个错误:

File "./PyZWServer.py", line 115, in IsRunning
  return (subprocess.Popen(["pgrep", "-c", "-x", name], stdout=subprocess.PIPE).communicate()[0] == "0")
File "/usr/lib/python2.6/subprocess.py", line 698, in communicate
  self.wait()
File "/usr/lib/python2.6/subprocess.py", line 1170, in wait
  pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
File "/usr/lib/python2.6/subprocess.py", line 465, in _eintr_retry_call
   return func(*args)
OSError: [Errno 10] No child processes
Error happened during handling of client
Run Code Online (Sandbox Code Playgroud)

kob*_*las 5

如果为SIGCHLD添加信号处理程序,则内核将处理wait/reap部分.

特别是这条线:

signal.signal(signal.SIGCHLD, signal.SIG_IGN)
Run Code Online (Sandbox Code Playgroud)

将照顾你的僵尸.

  • 在解决这个问题时,面临的挑战是communication()会采取一系列行为。如果您包装了自己的Popen并构造了一个信号处理程序,则由于传递了SIGCHLD信号,communcicate()可能会因读取的中断而中止(不会重试)。因此,“正确”的解决方案是让您拥有可以满足您需要的Popen版本。另一种选择是,对于不想僵死的进程,您需要对其进行双重包装,以便可以获取父级让自己的子孩子继续前进 (2认同)