Re: waitid() function replacement
Re: waitid() function replacement
- Subject: Re: waitid() function replacement
- From: Eric Gouriou <email@hidden>
- Date: Thu, 6 Apr 2006 20:45:16 -0700
On Apr 6, 2006, at 10:45 , Kevin Harris wrote:
To further clarify, what I need to be able to do is find out if the
processes my program spawns has terminated (without cleaning them
up). After I know the process is done, I need to signal the rest
of the process group to clear out any processes it may have spawned
(that haven't changed to a new process group). I can't use waitpid
() to find out if the process has quit and then signal the process
group.
I am wondering whether I am missing something.
According to the man page, Darwin supports
pid = waitpid(0, &status, WNOHANG);
Isn't this providing exactly what you are looking for ? If 0 is
returned,
it means there is no pending zombie child to reap, and you can kill()
the
process group of interest.
To avoid getting SIGCHLD delivered, something along the lines of this
should work:
struct sigactio action = {
.__sigaction_u.handler = SIG_HOLD,
.sa_flags = SA_NOCLDSTOP,
};
sigemptyset(&action.sa_mask);
sigaction(SIGCHLD, &action);
You might want to check that system() still works after blocking
sigaction. I believe I heard of some (old?) OSes where system() would
hang
in this case.
Playing with the signal handlers to act on SIGCHLD could be fairly
difficult (but not impossible), as my program spawns these
processes from different threads, and there is no guarantee which
of my threads will receive the signal. I'll look at this to see if
I can come up with anything.
If you have threads, you really want to block most signals anyway and
use sigwait in a specially designated thread to monitor all signals
you want to handle. So blocking SIGCHLD is probably something you
want to do no matter what.
The only somewhat easy alternative (ugly hack) I could come up with
is to spawn a second process that I don't care about, and place it
in the same process group.
Thanks, this forced me to look at the setpgid() man page. I hadn't
realized that one could set the process group to an arbitrary value
(I only every used the equivalent of setpgid(0, 0); ).
This process could be blocked on input, permanently sleeping, or
doing something else that uses little resources. After waiting on
the process I care about, the entire group (which will still be
active because of this second useless process) can then be safely
signalled.
It looks like this would work. Another option is to use the first fork
as a launcher process after it has setpgid(0, 0);, set a SIGCHLD
sigaction
with SA_NOCLDWAIT (to reap zombies without requiring a wait()), and
sleep() forever.
But I don't think you need this. As I said, I could be missing
something,
but I believe waitpid() gives you a way to avoid the race you are
concerned
about.
I hope this helps, this was the intent,
Eric
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden