Unix Programming - couple of questions on waitpid and children

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > September 2007 > couple of questions on waitpid and children





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author couple of questions on waitpid and children
Daniel C. Bastos

2007-09-15, 7:16 pm

If my process handles just one child, do I have the need for WNOHANG in
waitpid? I currently wrote the function below, but I'm thinking that I
only need waitpid there because I want WUNTRACED since I want to detect
SIGSTOP signals. Is this true?

static void sigchild(int sig)
{
pid_t pid; int stat;

for (;;) {
pid = waitpid(-1, &stat, WNOHANG | WUNTRACED);
if (pid <= 0)
break;

if (WIFEXITED(stat) ) {
died = 1;
}

if (WIFSTOPPED(stat)) {
stopped = 1;
}
}
}

How can I recognize the child has received a SIGCONT?
David Schwartz

2007-09-15, 7:16 pm

On Sep 15, 9:19 am, dbas...@yahoo.com.br (Daniel C. Bastos) wrote:

> for (;;) {
> pid = waitpid(-1, &stat, WNOHANG | WUNTRACED);
> if (pid <= 0)
> break;
>
> if (WIFEXITED(stat) ) {
> died = 1;
> }
>
> if (WIFSTOPPED(stat)) {
> stopped = 1;
> }
> }


Your code really doesn't make any sense. The 'WNOHANG' flag says "I
don't want to wait until something happens". Your "for(;;)" says "I
want to wait forever no matter what happens". Your "if (pid <= 0)
break;" says "I want to stop if there's nothing to do". These three
things are mutually inconsistent, so whatever it is you're trying to
do, this definitely isn't the way to do it.

DS

Martin Vuille

2007-09-15, 7:16 pm

David Schwartz <davids@webmaster.com> wrote in
news:1189900585.777967.160140@y42g2000hsy.googlegroups.com:

> On Sep 15, 9:19 am, dbas...@yahoo.com.br (Daniel C. Bastos)
> wrote:
>
>
> Your code really doesn't make any sense. The 'WNOHANG' flag says
> "I don't want to wait until something happens". Your "for(;;)"
> says "I want to wait forever no matter what happens". Your "if
> (pid <= 0) break;" says "I want to stop if there's nothing to
> do". These three things are mutually inconsistent, so whatever
> it is you're trying to do, this definitely isn't the way to do
> it.
>


How would you recommend expressing: "I want to reap all children
until there are no more children to be reaped, and then exit the
signal handler"?

MV

--
I do not want replies; please follow-up to the group.
Barry Margolin

2007-09-16, 1:31 am

In article <Xns99ACCB833B025jpmvrealtime@198.186.190.155>,
Martin Vuille <jpmv27@yahoo.com> wrote:

> David Schwartz <davids@webmaster.com> wrote in
> news:1189900585.777967.160140@y42g2000hsy.googlegroups.com:
>

I think this is wrong. If he has children that are still running, he
doesn't want to block until they exit. He just wants to reap all the
children that have exited at the time the signal handler runs.
[vbcol=seagreen]
> How would you recommend expressing: "I want to reap all children
> until there are no more children to be reaped, and then exit the
> signal handler"?


But you said in your original message that your process only has one
child. In that case it should be safe for your SIGCHLD handler to just
call waitpid() once, without WNOHANG.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
David Schwartz

2007-09-16, 1:31 am

On Sep 15, 5:00 pm, Martin Vuille <jpm...@yahoo.com> wrote:

> How would you recommend expressing: "I want to reap all children
> until there are no more children to be reaped, and then exit the
> signal handler"?


if (fork()!=0) _exit(0);

Or did you mean all children that need to be reaped *now*?

DS

Martin Vuille

2007-09-16, 1:31 am

Barry Margolin <barmar@alum.mit.edu> wrote in
news:barmar-F5C977.22281115092007@comcast.dca.giganews.com:

> In article <Xns99ACCB833B025jpmvrealtime@198.186.190.155>,
> Martin Vuille <jpmv27@yahoo.com> wrote:
>
>
>
> But you said in your original message that your process only has
> one child. In that case it should be safe for your SIGCHLD
> handler to just call waitpid() once, without WNOHANG.
>


I was not the OP. I'm just someone who has used similar code, and was
curious about a better way to do things.

MV

--
I do not want replies; please follow-up to the group.
Martin Vuille

2007-09-16, 1:31 am

David Schwartz <davids@webmaster.com> wrote in
news:1189910332.248328.141800@19g2000hsx.googlegroups.com:

> On Sep 15, 5:00 pm, Martin Vuille <jpm...@yahoo.com> wrote:
>
>
> if (fork()!=0) _exit(0);
>
> Or did you mean all children that need to be reaped *now*?
>


I must be really confused because I don't see how the above allows a
parent process to spawn children and then monitor their state (i.e.,
to know when they exit) and reap them so that there are no zombies
left around.

MV

--
I do not want replies; please follow-up to the group.
Daniel C. Bastos

2007-09-16, 1:31 am

Barry Margolin <barmar@alum.mit.edu> writes:

> In article <Xns99ACCB833B025jpmvrealtime@198.186.190.155>,
> Martin Vuille <jpmv27@yahoo.com> wrote:
>
>
> I think this is wrong. If he has children that are still running, he
> doesn't want to block until they exit. He just wants to reap all the
> children that have exited at the time the signal handler runs.


That's correct, although this does not apply to my case because I am in
need of only one child; but I had this function sort of written this way
for a long time, and I just copied it over to this program. But if later
I decided to handle more children, then the work of reaping them all
will be done already.

Barry Margolin's reasoning above is the same that Richard Stevens shows
in UNIX Network programming when he shows that if too many children all
exist at about the same time, a call to wait() will not suffice to avoid
zombie processes.

>
> But you said in your original message that your process only has one
> child. In that case it should be safe for your SIGCHLD handler to just
> call waitpid() once, without WNOHANG.


Okay; that's a ``yes'' to my question --- now snipped without a trace.
Daniel C. Bastos

2007-09-16, 1:31 am

dbast0s@yahoo.com.br (Daniel C. Bastos) writes:

> Barry Margolin <barmar@alum.mit.edu> writes:
>
>
> That's correct, although this does not apply to my case because I am in
> need of only one child; but I had this function sort of written this way
> for a long time, and I just copied it over to this program. But if later
> I decided to handle more children, then the work of reaping them all
> will be done already.
>
> Barry Margolin's reasoning above is the same that Richard Stevens shows
> in UNIX Network programming when he shows that if too many children all
> exist at about the same time, a call to wait() will not suffice to avoid
> zombie processes.
>
>
> Okay; that's a ``yes'' to my question --- now snipped without a trace.


Actually that's a ``no'' to my first question.
Peter J. Holzer

2007-09-16, 7:26 am

On 2007-09-16 00:00, Martin Vuille <jpmv27@yahoo.com> wrote:
> David Schwartz <davids@webmaster.com> wrote in
> news:1189900585.777967.160140@y42g2000hsy.googlegroups.com:
>
>
> How would you recommend expressing: "I want to reap all children
> until there are no more children to be reaped, and then exit the
> signal handler"?


I think

while ((pid = waitpid(-1, &stat, WNOHANG | WUNTRACED)) > 0) {

if (WIFEXITED(stat) ) {
died = 1;
}

if (WIFSTOPPED(stat)) {
stopped = 1;
}
}

is slightly more readable.

hp


--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
David Schwartz

2007-09-17, 1:25 am

On Sep 15, 8:26 pm, Martin Vuille <jpm...@yahoo.com> wrote:

>
[vbcol=seagreen]
> I must be really confused because I don't see how the above allows a
> parent process to spawn children and then monitor their state (i.e.,
> to know when they exit) and reap them so that there are no zombies
> left around.


What this code does is rig things so that all children are inherited
by the parent of this process. It then becomes that process'
responsibility to reap them. Since that process created this process,
it should know how to deal with children.

DS

Martin Vuille

2007-09-17, 1:29 pm

David Schwartz <davids@webmaster.com> wrote in
news:1189991323.159925.178640@o80g2000hse.googlegroups.com:

> On Sep 15, 8:26 pm, Martin Vuille <jpm...@yahoo.com> wrote:
>
>
>
> What this code does is rig things so that all children are
> inherited by the parent of this process. It then becomes that
> process' responsibility to reap them. Since that process created
> this process, it should know how to deal with children.
>


Sorry, but I'm still following you.

The OP's problem was process P wanting to track the state of
its child process C using a SIGCHLD handler.

Where does the above code fit in? In P, in C, or in PP, the
parent of process P?

MV

--
I do not want replies; please follow-up to the group.
Rainer Weikusat

2007-09-17, 1:29 pm

David Schwartz <davids@webmaster.com> writes:
> On Sep 15, 9:19 am, dbas...@yahoo.com.br (Daniel C. Bastos) wrote:
>
>
> Your code really doesn't make any sense. The 'WNOHANG' flag says "I
> don't want to wait until something happens". Your "for(;;)" says "I
> want to wait forever no matter what happens". Your "if (pid <= 0)
> break;" says "I want to stop if there's nothing to do". These three
> things are mutually inconsistent, so whatever it is you're trying to
> do, this definitely isn't the way to do it.


This is a somewhat clumsy formulation of a standard 'idiom' in a
SIGCHLD handler:

while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/* do something with status */
}

and it calls waitpid in a loop until all children which can be reaped
without waiting for the next to die have been dealt with.

Daniel C. Bastos

2007-09-17, 1:29 pm

Martin Vuille <jpmv27@yahoo.com> writes:

> David Schwartz <davids@webmaster.com> wrote in
> news:1189991323.159925.178640@o80g2000hse.googlegroups.com:
>
>
> Sorry, but I'm still following you.
>
> The OP's problem was process P wanting to track the state of
> its child process C using a SIGCHLD handler.
>
> Where does the above code fit in? In P, in C, or in PP, the
> parent of process P?


He's talking about your request:

MV> How would you recommend expressing: "I want to reap all children
MV> until there are no more children to be reaped, and then exit the
MV> signal handler"?

And his answer is to terminate the parent right after forking the child;
that leaves the work to your program's parent, so the code fits in P
leaving the work to PP.

When you invoke a program through the shell, for example, the shell is
the parent of that process, but as the shell exits, the parent of the
shell becomes responsible to deal with the children of the shell. Many
times the parent of the shell is the init program which knows well know
how to take care of children. So he talks about a common technique when
dealign with children. But, you seem to want your program to get SIGCHLD
from your program's children, so you can't _exit() in P.
Martin Vuille

2007-09-17, 7:22 pm

dbast0s@yahoo.com.br (Daniel C. Bastos) wrote in
news:84vea9mbgm.fsf@blade3.toledo.com:

> Martin Vuille <jpmv27@yahoo.com> writes:
>
^
I forgot a "not" here.
[vbcol=seagreen]
>
> He's talking about your request:
>
> MV> How would you recommend expressing: "I want to reap all
> children MV> until there are no more children to be reaped, and
> then exit the MV> signal handler"?
>
> And his answer is to terminate the parent right after forking
> the child; that leaves the work to your program's parent, so the
> code fits in P leaving the work to PP.


I guess it is my bad for not making it clear from the outset that I
was asking the question in the same context as the OP's question,
i.e., in the context of a parent process that wants to monitor a
child process. Although how calling "_exit()" fits in with "...
then exit the signal handler" still puzzles me.

Anyway, it's now become evident that the OP's algorithm was
correct, even if it was not expressed in the most elegant way.

MV

--
I do not want replies; please follow-up to the group.
Scott Lurndal

2007-09-17, 7:22 pm

Martin Vuille <jpmv27@yahoo.com> writes:
>David Schwartz <davids@webmaster.com> wrote in
>news:1189900585.777967.160140@y42g2000hsy.googlegroups.com:
>
>
>How would you recommend expressing: "I want to reap all children
>until there are no more children to be reaped, and then exit the
>signal handler"?
>


signal(SIGCLD, SIG_IGN);

scott
Martin Vuille

2007-09-17, 7:22 pm

scott@slp53.sl.home (Scott Lurndal) wrote in
news:ZKCHi.9745$924.525@newssvr23.news.prodigy.net:

> Martin Vuille <jpmv27@yahoo.com> writes:
>
> signal(SIGCLD, SIG_IGN);
>


I was asking my question in the context of the OP's problem,
i.e., in the context of a process that wants to monitor the
status of its children. It's become painfully obvious that I
should have made that clear in my question.

Setting the handler to SIG_IGN does not let the parent process
monitor the state of the child.

MV


--
I do not want replies; please follow-up to the group.
Daniel C. Bastos

2007-09-18, 1:26 am

Martin Vuille <jpmv27@yahoo.com> writes:

> dbast0s@yahoo.com.br (Daniel C. Bastos) wrote in
> news:84vea9mbgm.fsf@blade3.toledo.com:
>
> ^
> I forgot a "not" here.
>
>
> I guess it is my bad for not making it clear from the outset that I
> was asking the question in the same context as the OP's question,
> i.e., in the context of a parent process that wants to monitor a
> child process. Although how calling "_exit()" fits in with "...
> then exit the signal handler" still puzzles me.


Well, in that case there's no signal handler. If you want to leave the
children for someone else to worry, you certainly don't catch SIGCHLD;
moreover, you have to terminate --- there's no other way to pass on the
responsibility.
Daniel C. Bastos

2007-09-18, 1:26 am

Martin Vuille <jpmv27@yahoo.com> writes:

> scott@slp53.sl.home (Scott Lurndal) wrote in
> news:ZKCHi.9745$924.525@newssvr23.news.prodigy.net:
>
>
> I was asking my question in the context of the OP's problem,
> i.e., in the context of a process that wants to monitor the
> status of its children. It's become painfully obvious that I
> should have made that clear in my question.
>
> Setting the handler to SIG_IGN does not let the parent process
> monitor the state of the child.


Nor avoids zombies; and SIG_IGN is the default behavior of SIGCHLD; the
signal() call above makes no sense to me.
Rainer Weikusat

2007-09-18, 7:30 am

dbast0s@yahoo.com.br (Daniel C. Bastos) writes:
> Martin Vuille <jpmv27@yahoo.com> writes:


[...]

> MV> How would you recommend expressing: "I want to reap all children
> MV> until there are no more children to be reaped, and then exit the
> MV> signal handler"?
>
> And his answer is to terminate the parent right after forking the child;
> that leaves the work to your program's parent, so the code fits in P
> leaving the work to PP.


Since the question involves a signal handler and the answer doesn't,
they don't seem to match each other.

> When you invoke a program through the shell, for example, the shell is
> the parent of that process, but as the shell exits, the parent of the
> shell becomes responsible to deal with the children of the shell.


This is wrong, cf

The parent process ID of all of the calling process' existing
child processes and zombie processes shall be set to the
process ID of an implementation-defined system process. That
is, these processes shall be inherited by a special system
process.
(SUS, exit)

In practice, this means that if a process with child processes (either
living or undead) exits, these child processes get re-parented to the
'process with pid 1 spawned by the kernel after it has booted', aka
init, which calls 'usually' (among other things) calls wait in a loop
to get rid of any zombies it may have inherited.
Rainer Weikusat

2007-09-18, 7:30 am

dbast0s@yahoo.com.br (Daniel C. Bastos) writes:

[...]
[vbcol=seagreen]

[...]
[vbcol=seagreen]
>
> Nor avoids zombies; and SIG_IGN is the default behavior of SIGCHLD; the
> signal() call above makes no sense to me.


If the action for the SIGCHLD signal is set to SIG_IGN, child
processes of the calling processes shall not be transformed
into zombie processes when they terminate. If the calling
process subsequently waits for its children, and the process
has no unwaited-for children that were transformed into zombie
processes, it shall block until all of its children terminate,
and wait(), waitid(), and waitpid() shall fail and set errno
to [ECHILD]. [Option End]
(SUS, 'Signal Concepts/ Signal Actions')

Daniel C. Bastos

2007-09-19, 7:20 pm

Rainer Weikusat <rweikusat@mssgmbh.com> writes:

> dbast0s@yahoo.com.br (Daniel C. Bastos) writes:
>
> [...]
>
>
> [...]
>
>
> If the action for the SIGCHLD signal is set to SIG_IGN, child
> processes of the calling processes shall not be transformed
> into zombie processes when they terminate. If the calling
> process subsequently waits for its children, and the process
> has no unwaited-for children that were transformed into zombie
> processes, it shall block until all of its children terminate,
> and wait(), waitid(), and waitpid() shall fail and set errno
> to [ECHILD]. [Option End]


Hm, on a FreeBSD 4.7, I read that this is the behavior when SA_NOCLDWAIT
is set which requires one to use sigaction directly. Which man page on
which system did you quote the above from?

From sigaction(2) @ FreeBSD 4.7-RELEASE-p28:

SA_NOCLDWAIT If this bit is set when calling sigaction() for the
SIGCHLD signal, the system will not create zombie
processes when children of the calling process
exit. If the calling process subsequently issues a
wait(2) (or equivalent), it blocks until all of the
calling process's child processes terminate, and
then returns a value of -1 with errno set to
ECHILD.
Rainer Weikusat

2007-09-20, 7:30 am

dbast0s@yahoo.com.br (Daniel C. Bastos) writes:
> Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>
> Hm, on a FreeBSD 4.7, I read that this is the behavior when SA_NOCLDWAIT
> is set which requires one to use sigaction directly. Which man page
> on which system did you quote the above from?


The quote contained the source.
Scott Lurndal

2007-09-21, 1:27 pm

dbast0s@yahoo.com.br (Daniel C. Bastos) writes:
>Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>
>
>Hm, on a FreeBSD 4.7, I read that this is the behavior when SA_NOCLDWAIT
>is set which requires one to use sigaction directly. Which man page on
>which system did you quote the above from?
>
>From sigaction(2) @ FreeBSD 4.7-RELEASE-p28:
>
> SA_NOCLDWAIT If this bit is set when calling sigaction() for the
> SIGCHLD signal, the system will not create zombie
> processes when children of the calling process
> exit. If the calling process subsequently issues a
> wait(2) (or equivalent), it blocks until all of the
> calling process's child processes terminate, and
> then returns a value of -1 with errno set to
> ECHILD.


From the standard:

http://www.opengroup.org/onlinepubs....html#tag_02_04

scroll down to SIG_IGN

scott
Daniel C. Bastos

2007-09-21, 7:22 pm

scott@slp53.sl.home (Scott Lurndal) writes:

> dbast0s@yahoo.com.br (Daniel C. Bastos) writes:
>
> From the standard:
>
> http://www.opengroup.org/onlinepubs....html#tag_02_04
>
> scroll down to SIG_IGN


Thanks. I apologize for my wrong comments, although I'm glad I now know
about them.
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com