BTW, what I want to do is: the main process will wait for children to
die, but it should not be blocked (non-blocking wait)
Regards,
yellow1912
This is a discussion on Strange problem with fork() and waitpid() - infinite loop - Unix ; I'm having problem with this very short piece of code: for(int i=0;i cout switch(pid = fork()) { case -1 : perror("fork"); cout _exit(1); break; case 0 : sleep(6); cout _exit(0); break; default: cout while ((pid = waitpid(-1, &Status, WNOHANG)) > ...
I'm having problem with this very short piece of code:
for(int i=0;i<5;i++){
cout<
switch(pid = fork()) {
case -1 :
perror("fork");
cout << "Can not fork \n";
_exit(1);
break;
case 0 :
sleep(6);
cout << "------------------Im outta here:"< _exit(0);
break;
default:
cout << "waiting \n";
while ((pid = waitpid(-1, &Status, WNOHANG)) > 0) {
sleep(1);
}
break;
}
sleep(1);
cout << "++++++++++\n"<
}
This code will run forever. If I remove the sleep(6) the problem is
solved, but it's probably not the cause. I think I'm having a race
condition where some where, but I really cant think of a way to solve
this. Any help is greatly appreciated.
Regards,
yellow1912
BTW, what I want to do is: the main process will wait for children to
die, but it should not be blocked (non-blocking wait)
Regards,
yellow1912
If you run the code in Shell Environment, and you got the result like
this:
/home/yourname>a.out
Arrived 0
waiting
++++++++++
Arrived 1
waiting
++++++++++
Arrived 2
waiting
++++++++++
Arrived 3
waiting
++++++++++
Arrived 4
waiting
++++++++++
/home/yourname>------------------Im outta here: 0
------------------Im outta here: 1
------------------Im outta here: 2
------------------Im outta here: 3
------------------Im outta here: 4
it seems that "This code will run forever", but the tip like "/home/
yourname>" would appear when the parent process exit. So u wouldnt get
a new tip "/home/yourname>" when the child exit.
If you remove the sleep(6), the child will exit before parent, then
you can get the new tip.
you can type "ps -A | grep a.out" on another terminal to confirm
whether the process has been ended.
BRs.
On Dec 7, 7:22 am, yellow1...@gmail.com wrote:
> I'm having problem with this very short piece of code:
> for(int i=0;i<5;i++){
> cout< >
> switch(pid = fork()) {
>
> case -1 :
> perror("fork");
> cout << "Can not fork \n";
> _exit(1);
> break;
> case 0 :
>
> sleep(6);
> cout << "------------------Im outta here:"< > _exit(0);
> break;
> default:
> cout << "waiting \n";
> while ((pid = waitpid(-1, &Status, WNOHANG)) > 0) {
> sleep(1);
> }
>
> break;
> }
> sleep(1);
>
> cout << "++++++++++\n"<>
> }
>
> This code will run forever. If I remove the sleep(6) the problem is
> solved, but it's probably not the cause. I think I'm having a race
> condition where some where, but I really cant think of a way to solve
> this. Any help is greatly appreciated.
>
> Regards,
> yellow1912
On Dec 6, 8:13 pm, Fatfishwrote:
> If you run the code in Shell Environment, and you got the result like
> this:
>
> /home/yourname>a.out
> Arrived 0
> waiting
> ++++++++++
> Arrived 1
> waiting
> ++++++++++
> Arrived 2
> waiting
> ++++++++++
> Arrived 3
> waiting
> ++++++++++
> Arrived 4
> waiting
> ++++++++++
> /home/yourname>------------------Im outta here: 0
> ------------------Im outta here: 1
> ------------------Im outta here: 2
> ------------------Im outta here: 3
> ------------------Im outta here: 4
>
> it seems that "This code will run forever", but the tip like "/home/
> yourname>" would appear when the parent process exit. So u wouldnt get
> a new tip "/home/yourname>" when the child exit.
> If you remove the sleep(6), the child will exit before parent, then
> you can get the new tip.
>
> you can type "ps -A | grep a.out" on another terminal to confirm
> whether the process has been ended.
>
> BRs.
>
> On Dec 7, 7:22 am, yellow1...@gmail.com wrote:
>
> > I'm having problem with this very short piece of code:
> > for(int i=0;i<5;i++){
> > cout<
>
> > switch(pid = fork()) {
>
> > case -1 :
> > perror("fork");
> > cout << "Can not fork \n";
> > _exit(1);
> > break;
> > case 0 :
>
> > sleep(6);
> > cout << "------------------Im outta here:"< > > _exit(0);
> > break;
> > default:
> > cout << "waiting \n";
> > while ((pid = waitpid(-1, &Status, WNOHANG)) > 0) {
> > sleep(1);
> > }
>
> > break;
> > }
> > sleep(1);
>
> > cout << "++++++++++\n"<
>
> > }
>
> > This code will run forever. If I remove the sleep(6) the problem is
> > solved, but it's probably not the cause. I think I'm having a race
> > condition where some where, but I really cant think of a way to solve
> > this. Any help is greatly appreciated.
>
> > Regards,
> > yellow1912
Ahhh. I see what you mean. So the parents actually exit first (I was
wondering why I see "/home/yourname" while running it).
Is there a way to fix the above code, so that the parent will fork as
many children as need without waiting, but will not quit before the
last child ends. I'm thinking if keeping track of the number of
children created and somehow decrease that everytime a child ends.
Regards,
yellow1912
Sorry about the different "nick" in the previous post. it was me using
a friend's computer and forgot to log out.
yellow1912
I add another loop for wait just above return:
for(int i=0;i<5;i++){ wait(&Status);}
This will make sure that the main program will never exit before all
its children exit.
This seems to solve the problems:
1. Parent should fork children whenever asked to, and should not do
blocking wait.
2. As soon as a child dies, free its resource
3. Parent must exit only when the last child dies.
Do you think this is an acceptable solution?
In article
,
konkitowrote:
> Is there a way to fix the above code, so that the parent will fork as
> many children as need without waiting, but will not quit before the
> last child ends. I'm thinking if keeping track of the number of
> children created and somehow decrease that everytime a child ends.
You don't need a counter. wait() will report the error ECHILD if you no
longer have any children.
Take the calls to waitpid() out of your fork loop. Use one loop to fork
all the children, then use a separate loop to call wait() until it
reports ECHILD.
Or you could use a SIGCLD signal handler to be notified when a child has
exited. The handler should call waitpid() in a loop until it returns 0
or -1.
--
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 ***
> Take the calls to waitpid() out of your fork loop. Use one loop to fork
> all the children, then use a separate loop to call wait() until it
> reports ECHILD.
I'm working under an environment that limits the number of processes
can run at once, so I need to terminate any child as soon as it exits.
I can not afford to wait till the end.
> Or you could use a SIGCLD signal handler to be notified when a child has
> exited. The handler should call waitpid() in a loop until it returns 0
> or -1.
I would really appreciate it if you can give a very short piece of
code to explain how you do it, or may be a link to somewhere. I have
spent the wholeday looking all over the net and this group but I still
don't pretty much get it, especially the way sig handler works.
Thank you so much for your time and kindness.
Regards,
yellow1912
> I would really appreciate it if you can give a very short piece of
> code to explain how you do it, or may be a link to somewhere. I have
Stevens' APUE gives the perfect explain about process environ, process
control,
and process relationship, etc.
> spent the wholeday looking all over the net and this group but I still
> don't pretty much get it, especially the way sig handler works.
I consider that grep new knowledge from net is not a good way. Spend
more time
on an entire chapter from classical books is more efficient.
Recommend: APUE, Beginning Linux Programming to start.
yellow1912@gmail.com writes:
[...]
> cout << "waiting \n";
> while ((pid = waitpid(-1, &Status, WNOHANG)) > 0) {
> sleep(1);
> }
The waitpid call will return 0 when WNOHANG is given and no child has
exited yet. It should work when testing for >= 0. As soon as all
children have exited, it would return -1, errno == ECHILD.