Find the answer to your Linux question:
Results 1 to 4 of 4
Hi gurus, I would like to fork more children and then write their return values: so far I tried: Code: #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Posts
    70

    waiting for multiple childs - C - waitpid


    Hi gurus, I would like to fork more children and then write their return values: so far I tried:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main(void)
    {
            pid_t pid;
            int rv=0, i;
            pid_t child_pids[5];
    
    
            for (i=1; i<=5; i++){
    
                    /* Multiple child forking */
                    switch(pid = fork()){
                            case -1:
                                    /* something went wrong */
                                    /* parent exits */
                                    perror("fork");
                                    exit(1);
    
                            case 0:
                                    /*Children process*/
                                    child_pids[i] = getpid();
                                    printf(" CHILD: number (and return value): %d PID: %d PPID: %d \n", i, getpid(), getppid());
                                    exit(i);
                                    break;
    
                                    /*Missing code for parent process - will be executed out of loop*/
                    }
            }
            /*Parent process*/
            if (pid!=0 && pid!=-1) {
                    printf("PARENT: my PID is %d\n", getpid());
    
                    for (i=1; i<=5; i++){
                            waitpid(child_pids[i], NULL, 0);
                            printf("PARENT: Child: %d returned value is: %d\n", i, WEXITSTATUS(child_pids[i]));
                    }
            }
    }
    But returns any random variables for child process:

    ...
    PARENT: Child: 3 returned value is: 13
    PARENT: Child: 3 returned value is: 127
    ...


    also tried following
    Code:
    int main(void)
    {
            pid_t pid;
            int rv=0, i;
            pid_t child_pids[5];
            int child_state = 9;
            pid_t rc_pid;
    
    
            for (i=1; i<=5; i++){
    
                    /* Multiple child forking */
                    switch(pid = child_pids[i] = fork()){
                            case -1:
                                    /* something went wrong */
                                    /* parent exits */
                                    perror("fork");
                                    exit(1);
    
                            case 0:
                                    /*Children process*/
                                    //child_pids[i] = getpid();
                                    printf(" CHILD: number (and return value): %d PID: %d PPID: %d \n", i, getpid(), getppid());
                                    exit(i);
                                    break;
    
                                    /*Missing code for parent process*/
                    }
            }
            /*Parent process*/
            if (pid!=0 && pid!=-1) {
                    printf("PARENT: my PID is %d\n", getpid());
    
                    for (i=1; i<=5; i++){
                            rc_pid = waitpid(child_pids[i], NULL, 0);
                            printf("PARENT: Child: %d returned value is: %d\n", i, WEXITSTATUS(child_pids[i]));
                    }
            }
    }
    but returns always number 19 as return code of children
    ...
    PARENT: Child: 4 returned value is: 19
    ...

    Probably something something is wrong with waitpid() function
    Thanks a lot.

  2. #2
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    WEXITSTATUS doesn't take a PID as an argument.

  3. #3
    Just Joined!
    Join Date
    Jul 2009
    Posts
    70
    Quote Originally Posted by markcole View Post
    WEXITSTATUS doesn't take a PID as an argument.
    I found solution on another forum

    Code:
    int status;
    
    waitpid(child_pids[i], &status, 0);
    
    printf("PARENT: Child: %d returned value is: %d\n", child_pids[i], WEXITSTATUS(status));
    Just one question is this right way to create children ?

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,755
    In your first example, you have the child populating an array that the parent is looking at. Wrong! At the point after the fork, the child has a copy of parent's memory, but it is NOT shared. So, the random cruft you are seeing from the parent is to be expected. It's whatever was in that memory when the array was instantiated. Also, C/C++ use zero-based array indexing,
    hence my change to your loops, otherwise you are asking for a core dump.

    So, in your fork() loop, try this:
    Code:
    int main(void)
    {
            pid_t pid;
            int rv=0, i;
            pid_t child_pids[5];
    
            for (i=0; i < 5; i++){
    
                    /* Multiple child forking */
                    switch(pid = fork()){
                            case -1:
                                    /* something went wrong */
                                    /* parent exits */
                                    perror("fork");
                                    exit(1);
    
                            case 0:
                                    /*Children process*/
                                    pid = getpid();
                                    printf(" CHILD: number (and return value): %d PID: %d PPID: %d \n", i, pid, getppid());
                                    exit(i);
                                    break;
    
                                    /*Missing code for parent process*/
                            default:
                                    /* Parent process */
                                    child_pids[i] = pid;
                                    break;
                    }
            }
            /*Parent process*/
            if (pid!=0 && pid!=-1) {
                    printf("PARENT: my PID is %d\n", getpid());
    
                    for (i=0; i<5; i++){
                            int status = 0;
                            printf("PARENT: waiting for child %d (%d)\n", i, child_pids[i]);
                            rc_pid = waitpid(child_pids[i], &status, 0);
                            printf("PARENT: Child: %d returned value is: %d\n", i, WEXITSTATUS(status));
                    }
            }
    }
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •