Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Popen to run backgroud process and avoid zombie?

I've a listener server running new thread to for each client handler. Each handler can use:

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

to run new process in background, after what the handler thread is ended.

After the background process is ended, it is kept in Z state. Is it possible to ask subprocess.Popen() to handle SIG_CHILD to avoid this zombie?

I don't want to read process state using proc.wait(), since for this I've to save the list of all running background processes...

UPD

I need to run some processes in background avoiding zombies and to run some processes with .communicate() to read data from these processes. In that case using signal trick from koblas I get an error:

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
like image 539
PoltoS Avatar asked Jun 22 '11 15:06

PoltoS


People also ask

How to avoid zombie process?

By ignoring the 'SIGCHLD' signal: When a child is terminated, a corresponding SIGCHLD signal is delivered to the parent, if we call the 'signal(SIGCHLD,SIG_IGN)', then the SIGCHLD signal is ignored by the system, and the child process entry is deleted from the process table Thus, no zombie is created.

How to prevent a child process to become long term zombies?

To prevent of zombie processes you need to tell the parent to wait for the child, until the child's terminates the process. Down here you have an example code that you can use the waitpid() function. #include <unistd.

What creates zombie processes?

A process in Unix or Unix-like operating systems becomes a zombie process when it has completed execution but one or some of its entries are still in the process table. If a process is ended by an "exit" call, all memory associated with it is reallocated to a new process; in this way, the system saves memory.

Why does the operating system maintain the state of zombie processes?

Zombie processes allow the parent to be guaranteed to be able to retreive exit status, accounting information, and process id for child processes, regardless of whether the parent calls wait() before or after the child process exits. This is why a zombie process is necessary.


1 Answers

If you add a signal handler for SIGCHLD you will have the kernel handle the wait/reap piece.

Specifically the line:

signal.signal(signal.SIGCHLD, signal.SIG_IGN)

Will take care of your Zombies.

like image 55
koblas Avatar answered Sep 21 '22 19:09

koblas