0
votes

I wrote a program that creates multiple processes with fork(). Now I'm trying to make it so that each time I call fork(), only the original parent process produces children. For instance, if I give an argument of 4, I should have all 4 ppid's be the same and its children.

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

int main(int argc, char **argv) {

    int i;
    int n;
    int num_kids;

    if(argc != 2) {
        fprintf(stderr, "Usage: forkloop <numkids>\n");
        exit(1);
    }

    num_kids = atoi(argv[1]);

    for(i = 0; i < num_kids; i++) {
        n = fork();
        if(n < 0) {
            perror("fork");
            exit(1);
        } else if (n == 0) {
            exit(i);
        }
        printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i);
    }

    return 0;
}

When I run this, each ppid is the same but each child pid is the same as well. If I give in 4 as my argument, I get:

pid = 19765, ppid = 18449, i = 0
pid = 19765, ppid = 18449, i = 1
pid = 19765, ppid = 18449, i = 2
pid = 19765, ppid = 18449, i = 3

Should the child pid's all be the same, or is there something wrong with my code?

3
The child process exit's right away, the process that's doing those print-outs is the parent process (the same process each time).skyking
Please don't deface your question.rene

3 Answers

2
votes

Don't be confused with return value of fork():

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

int main(int argc, char **argv) {

    int i;
    int n;
    int num_kids;

    if(argc != 2) {
        fprintf(stderr, "Usage: forkloop <numkids>\n");
        exit(1);
    }

    num_kids = atoi(argv[1]);

    printf("parent pid = %d\n", getpid());
    for(i = 0; i < num_kids; i++) {
        n = fork();
        if(n < 0) {
            perror("fork");
            exit(1);
        }
        else if (n == 0) { // child process
            printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i);
            exit(i);
        }
    }

    return 0;
}

Output:

parent pid = 54981
pid = 54982, ppid = 54981, i = 0
pid = 54983, ppid = 54981, i = 1
pid = 54984, ppid = 54981, i = 2
pid = 54985, ppid = 54981, i = 3
1
votes

This link explains things for you.

In your case when you wrote the line

 printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i);

this line was handled by parent process and not the child process. Variable "n" stores the return value after fork is created (which is 0 when created successfully). So in order to get the process ID of child you have to out your code inside

else if (n == 0) {  //child process
        exit(i);
    }

Hope it helped.

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

Incorrect order of headers. sys/ headers not only should always go first, the manpage for getpid and getppid specifically places sys/types.h above unistd.h.

int main(int argc, char **argv) {

    int i;
    int n;
    int num_kids;

    if(argc != 2) {
        fprintf(stderr, "Usage: forkloop <numkids>\n");
        exit(1);
    }

    num_kids = atoi(argv[1]);

    for(i = 0; i < num_kids; i++) {
        n = fork();

n is a bad name for a pid of the child.

        if(n < 0) {
            perror("fork");
            exit(1);
        } else if (n == 0) {
            exit(i);

Incorrect. Should be _Exit.

        }
        printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i);

This line is executed by your original process. Perhaps you wanted to execute it in the child. But the child just exits. }

    return 0;
}