Thread: Confused on correct way to handle child processes

  1. #1
    Registered User
    Join Date
    Jul 2015
    Posts
    33

    Confused on correct way to handle child processes

    I'm having a bit of trouble handling waiting for child processes to finish.

    Code:
    while (true) {
        child_proc_cleanup();
    
        spawnpid = fork();
    
        if (spawnpid == 0) {
            // child
            ...
            std::cout << "FINISH" << std::endl;
        } else if (spawnpid > 0) {
            // child_proc_cleanup();
            // child_proc_cleanup(spawnpid);
        } else {
            // error
        }
    }
    
    void child_proc_cleanup() {
        pid_t c_pid;
        int c_status;
        
        while ((c_pid = waitpid(-1, &c_status, WNOHANG)) > 0) {
            //
        }
    }
    
    void child_proc_cleanup(pid_t spawnpid) {
        pid_t c_pid;
        int c_status;
        
        while ((c_pid = waitpid(spawnpid, &c_status, WNOHANG)) > 0) {
            //
        }
    }
    It seems no matter where I place the child_proc_cleanup(), whenever the child process outputs FINISH, it is still listed when I run `ps -ef | grep <user>.

    I think I'm misunderstanding the use of waitpid and how to properly avoid zombie processes. Do I need to call kill() as well?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Yes, you're mis-understanding how waitpid works.
    You got the return result test wrong.

    Further, you don't explain how child exits your while(true) loop. Does it go round again and make further children of it's own?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main(void) {
      pid_t p;
      p = fork();
      if ( p == 0 ) {
        printf("This is child %d\n", getpid() );
        sleep(10);
        printf("Child exiting\n");
        exit(0);
      } else if ( p > 0 ) {
        int status;
        printf("This is parent of child %d\n", p );
        while ( waitpid(p, &status, WNOHANG) == 0 ) {
          printf("Still waiting\n");
          sleep(1);
        }
        if ( WIFEXITED(status) ) {
          printf("Child exited normally with status %d\n",WEXITSTATUS(status));
        }
      }
      else {
        fprintf(stderr,"Bad fork, try a spoon\n");
      }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jul 2015
    Posts
    33
    Quote Originally Posted by Salem View Post
    Yes, you're mis-understanding how waitpid works.
    You got the return result test wrong.

    Further, you don't explain how child exits your while(true) loop. Does it go round again and make further children of it's own?
    Oh I think that's what it's doing? I assumed that once it finishes the last line of execution (e.g std::cout << "FINISH" << std::endl;) it would end itself. The while(true) loop is for the main parent process. If that's not true, is there a call I need to make?

    The reason I didn't put anything in my waitpid() check is because I don't care about printing the results, just want it to wait until the child process finishes.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > Oh I think that's what it's doing?
    Unless you specifically call exit(), or call an exec() function, or fall off the end of main() (or crash with an unhandled exception), your child process is just going to follow the usual program flow.

    > I assumed that once it finishes the last line of execution (e.g std::cout << "FINISH" << std::endl it would end itself.
    Why would you think that?
    Did you think the child exited automatically at the matching closing brace of the if statement?


    > If that's not true, is there a call I need to make?
    Yes Dorothy, look at my example.
    What do you see on line 14?

    > The reason I didn't put anything in my waitpid() check is because I don't care about printing the results,
    > just want it to wait until the child process finishes.
    Maybe so, but you got the >0 in your loop, not ==0.
    Quote Originally Posted by manpage
    waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was speci‐
    fied and one or more child(ren) specified by pid exist, but have not yet changed state, then 0 is
    returned
    . On error, -1 is returned.
    Your attempt at waiting executed exactly once before giving up.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 12-01-2013, 02:00 PM
  2. Child processes
    By jsx-27 in forum C Programming
    Replies: 3
    Last Post: 08-24-2012, 02:27 AM
  3. Passing a handle between processes
    By axr0284 in forum C++ Programming
    Replies: 1
    Last Post: 12-16-2005, 04:10 PM
  4. Child processes in Linux
    By Music_Man in forum Linux Programming
    Replies: 0
    Last Post: 03-20-2003, 09:04 AM
  5. Getting window handle from processes ID?
    By no-one in forum Windows Programming
    Replies: 4
    Last Post: 04-28-2002, 01:04 PM

Tags for this Thread