Fábio Silva
Fábio Silva

Reputation: 31

How to fork() n child processes doing diferrent functions?

This is my code:

for (c = 0; c < PROCESSES; c++) {
    pid[c] = fork();
    switch (pid[c]) {
        case -1:
            perror("Faild fork!\n");
            break;
        case 0:
            printf("C = %d\n", c);
            if (c == 0) {
                printf("MY ID0 %d\n", getpid());
                customers();
                break;
            }
            if (c == 1) {
                printf("MY ID1 %d\n", getpid());
                cashier();
                break;
            }
            if (c == 2) {
                printf("MY ID2 %d\n", getpid());
                sales();
                break;
            }
            if (c == 3) {
                printf("MY ID3 %d\n", getpid());
                warehouse();
                break;
            }
            break;

        default:
            if (c == (PROCESSES - 1)) {

                for (j = 0; j < PROCESSES; j++) {
                    w = wait(&state);
                    if (w == -1) {
                        perror("Erro na espera!\n");
                    }
                    printf("Terminar processo %d\n", w);
                }
                sleep(2);
                printf("Fim da simulação.\n\n");
                free_shm_sem();
            }

    }
}

What I was expecting to happen:

C = 0
MY ID0 3904
C = 1
MY ID1 3905
C = 2
MY ID2 3906
C = 3
MY ID3 3907

what happened:

C = 0
MY ID0 3904
C = 1
MY ID1 3905
C = 2
MY ID2 3906
C = 3
MY ID3 3907
C = 3
MY ID3 3911

If I change to:

            if (c == 0) {
                printf("MY ID0 %d\n", getpid());
                customers();
                break;
            }
            if (c == 1) {
                printf("MY ID1 %d\n", getpid());
                sales();
                break;
            }
            if (c == 2) {
                printf("MY ID2 %d\n", getpid());
                cashier();
                break;
            }
            if (c == 3) {
                printf("MY ID3 %d\n", getpid());
                warehouse();
                break;
            }

The output became:

C = 0
C = 2
C = 1
MY ID0 3960
MY ID2 3962
C = 3
MY ID1 3961
MY ID3 3963
C = 2
MY ID2 3967
C = 3
MY ID3 3968

Why c changes its value and some times passes through the same place twice?

This isnt the right way of fork() n childs doing diferent processes?

P.S. Sorry my English is bad. I hope you can understand what I said.

Upvotes: 3

Views: 2659

Answers (3)

perreal
perreal

Reputation: 97948

Are you considering the fact that all your forked processes continue to iterate the for loop and fork more processes?

Consider the first iteration:

for (c = 0; c < PROCESSES; c++) { // c is 0

we do a fork:

 pid[c] = fork();

Now, in the child process, pid[0] is 0. So,

switch (pid[c]) {

Goes into:

case 0:
       if (c == 0) {
            printf("MY ID0 %d\n", getpid());
            customers();
            break;
        }

And does some printing. Then it goes out of switch. And c is 0. So it increments c to 1, and does:

 pid[c] = fork();

Forking a grand children.

To prevent this you can exit instead of break:

        if (c == 0) {
            printf("MY ID0 %d\n", getpid());
            customers();
            exit(0);
        }

Upvotes: 6

Some programmer dude
Some programmer dude

Reputation: 409176

For the processes that should do special handling (i.e. the four first) do a separate step calling fork for each of them in the parent process. Then do a loop creating all the generic processes that you might need.

Upvotes: 1

Karthik T
Karthik T

Reputation: 31952

First of all, fork starts parellel processes, there is no guarantee that it will run sequentially

Upvotes: 1

Related Questions