简体   繁体   中英

Creating Multiple Processes in C (Parent with several children)

I'm learning C and Linux at school. My task is to create a parent process, which creates 3 child processes. The created child processes shall not have further children. I have to show that all processes existing at same time. Thereafter the Parent shall wait for the termination of the created child processes.

This is my code:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
    int i;
    int var = 0;
    printf("I am the Parent, my ID: %d\n", getpid());
    for( i = 0; i < 3; i++ ) {
        if(var == 0) {
            if( fork() == 0 ) {
                var++;
                printf("Child: PID: %d; PPID: %d\n", getpid(), getppid() );
                printf("Var:%d \n", var);
            }
        }
    }
    sleep(3);
    int status;
    wait(&status);
    printf("%d says bye!\n", getpid());
}

my output:

I am the Parent, my ID: 273
Child: PID: 274; PPID: 273
Var:1 
Child: PID: 275; PPID: 273
Var:1 
Child: PID: 276; PPID: 273
Var:1 

I also tried with WEXITSTATUS() which I printed out, but it's only the parent process, which he states with 0.

This code creates a parent process and its 3 child processes without further children as excepted. But how do I let parent wait for 3 children to terminate and how do I show/proof that all processes can exist at same time?

Let's start with what's wrong with your current code:

  1. You are not separating parent/child code by explicitly terminating the children when needed. Each child in your code will continue executing the for loop and then the code after it doing the wait() , which should only be executed by the parent.

  2. You are not waiting for all the children. If you create 3 children, then 3 wait() calls will need to be made, one for each child. In your case the order doesn't really matter, so you can use wait() instead of waitpid() / wait3() / wait4() , but you'll need another loop.

  3. You are not checking for errors on any of the functions you use. You definitely should!

  4. I'm kind of missing the point of your var variable, if the intent is to just avoid entering the loop body in the child code, then a simple break , exit() or return will suffice.

A correct version of your code would be the following:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>

int main() {
    unsigned i;
    int status;
    pid_t child_pid;

    printf("I am the Parent, my PID: %d\n", getpid());

    for (i = 0; i < 3; i++) {
        child_pid = fork();

        if (child_pid == -1) {
            perror("fork() failed");
            return 1;
        } else if (child_pid == 0) {
            printf("Child: PID: %d; PPID: %d\n", getpid(), getppid() );
            sleep(3);
            printf("Child %d says bye!\n", getpid());
            return 0;
        }
    }

    for (i = 0; i < 3; i++) {
        child_pid = wait(&status);
        if (child_pid == -1) {
            perror("wait() failed");
            return 1;
        }

        if (WIFEXITED(status)) {
            printf("Child %d exited with code %d\n", child_pid, WEXITSTATUS(status));
        } else {
            // Handle other cases here like WIFSIGNALED, WIFSTOPPED, etc...
            // See `man 2 wait` for more information.
        }
    }

    return 0;
}

how do I show/proof that all processes can exist at same time?

This can be done in a lot of different ways. You could do this externally on another terminal by using programs like ps after the 3 child are spawned (maybe increase the sleep to 10 seconds to have more time):

$ ps --ppid 249626 # get this from the output of your program
    PID TTY          TIME CMD
 249627 pts/1    00:00:00 test
 249628 pts/1    00:00:00 test
 249629 pts/1    00:00:00 test

Or you could do this by printing the time of start and end of execution within your program in the children code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <time.h>

void print_time(void) {
    time_t t;
    struct tm *local;
    const char *local_str;

    t = time(NULL);
    if (t == (time_t)-1) {
        perror("time() failed");
        return;
    }

    local = localtime(&t)
    if (local == NULL) {
        perror("localtime() failed");
        return;
    }

    local_str = asctime(&local);
    if (local_str == NULL) {
        perror("asctime() failed");
        return;
    }

    ptintf("Child %d time: %s\n", getpid(), local_str);
}

// ... same code as before ...

        } else if (child_pid == 0) {
            printf("Child %d PPID: %d\n", getpid(), getppid() );
            print_time();
            sleep(3);
            printf("Child %d says bye!\n", getpid());
            print_time();
            return 0;
        }

// ... same code as before ...

Output:

I am the Parent, my PID: 250469
Child 250470 PPID: 250469
Child 250471 PPID: 250469
Child 250470 time: Tue Oct 26 23:53:03 2021
Child 250472 PPID: 250469
Child 250471 time: Tue Oct 26 23:53:03 2021
Child 250472 time: Tue Oct 26 23:53:03 2021
Child 250470 says bye!
Child 250470 time: Tue Oct 26 23:53:06 2021
Child 250471 says bye!
Child 250471 time: Tue Oct 26 23:53:06 2021
Child 250472 says bye!
Child 250472 time: Tue Oct 26 23:53:06 2021
Child 250470 exited with code 0
Child 250471 exited with code 0
Child 250472 exited with code 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM