Hoffmann
Hoffmann

Reputation: 14719

How to check if a process with a pid X is a zombie?

I got the PID of a process and I need to check if it is a zombie using POSIX system calls in C. How should I do that?

The problem I'm having is that I have a process and it forks into many children, the children all do execs and sometimes I want to do the exec in background so I can't really wait() the children that go in background. I could wait() periodically (once in my main loop) but I need to know which processes are zombie so my father process doesn't hang while waiting for children that are not going to end soon.

If you are curious, I'm building a unix shell and it is in the shell nature to have the children processes behaving asynchronously.

Upvotes: 4

Views: 8447

Answers (5)

Yegor  Dubinker
Yegor Dubinker

Reputation: 21

And what about the shell command 'ps' which shows you the table of active processes where you can find that an process is 'defunct'? I suppose there must be a way to get that information from c code.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753655

Normally, the shell checks for defunct children shortly before printing its prompt - using the waitpid(2) system call and the WNOHANG option as already discussed. You might also want a SIGCHLD handler - but you'd have to decide what you're going to do with the information if you're busy waiting for some foreground process to terminate and it is actually a background process that terminates.

This is only a minor variation on the currently selected answer.

Upvotes: 1

DigitalRoss
DigitalRoss

Reputation: 146043

But .. but .. the zombie is a child (at some level) and the process that's checking is a parent, right? So if you are concerned that a specific pid is a zombie why not just do a waitpid(2) with WNOHANG and get rid of it? Now, this will consume the exit status, so it may be a bad idea if some other process might want to really wait in the future.

Upvotes: 3

Teddy
Teddy

Reputation: 6163

You mention that you are building a Unix shell; you should read this: Proper handling of SIGINT/SIGQUIT

Upvotes: 1

bdonlan
bdonlan

Reputation: 231103

You can't check whether a process is a zombie with pure POSIX calls - except where you're the parent process, and reaping it with a wait family call. So you'll have to find a good place to wait for the child.

One option is to set a SIGCHLD handler and do a waitpid(0, &status, WNOHANG) there. Be sure to loop until it no longer finds any processes - if two children die within a short interval, you may only get one SIGCHLD.

Another option is to double fork - that is, fork(), have the child (call it child A) fork again, have the second child (child B) exec. Then child A immediately exits. Meanwhile the parent is wait()ing for child A. Once child A is gone, the system's init process will take care of reaping child B when it eventually dies. This method is simpler, but your shell will have no way of knowing when child B dies, so if you need that information, use the former method.

Upvotes: 6

Related Questions