Strange problem with fork() and waitpid() - infinite loop - Unix

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)) > ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: Strange problem with fork() and waitpid() - infinite loop

  1. Strange problem with fork() and waitpid() - infinite loop

    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

  2. Re: Strange problem with fork() and waitpid() - infinite loop

    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

  3. Re: Strange problem with fork() and waitpid() - infinite loop

    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



  4. Re: Strange problem with fork() and waitpid() - infinite loop

    On Dec 6, 8:13 pm, Fatfish wrote:
    > 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

  5. Re: Strange problem with fork() and waitpid() - infinite loop

    Sorry about the different "nick" in the previous post. it was me using
    a friend's computer and forgot to log out.
    yellow1912

  6. Re: Strange problem with fork() and waitpid() - infinite loop

    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?

  7. Re: Strange problem with fork() and waitpid() - infinite loop

    In article
    ,
    konkito wrote:

    > 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 ***

  8. Re: Strange problem with fork() and waitpid() - infinite loop

    > 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

  9. Re: Strange problem with fork() and waitpid() - infinite loop

    > 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.

  10. Re: Strange problem with fork() and waitpid() - infinite loop

    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.