pensee
pensee

Reputation: 545

Statement getting executed multiple times when out of child-parent for loop

How to wait for all forked processes to terminate and then print the final value calculated in a
variable. I have the following c program. It calculates the sum of an array by distributing the array
among 10 different thread using fork(). But when I am out of the for loop which creates the
fork() and I print a value it gets printed multiple times.

    typedef struct
{
    int start;
    int end;
} range;
int main(int argc, char *argv[])
{
    int a[100];
    int totalSum = 0;
    for (int i = 0; i < 100; i++)
        a[i] = 1;
    int num_processes = 10;
    int pipefd[2 * num_processes][2];
    pid_t cpid;
    char buf;

    for (int i = 0; i < 2 * num_processes; i++)
    {
        if (pipe(pipefd[i]) == -1)
        {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }

    for (int i = 0; i < num_processes; i++)
    {
        cpid = fork();

        if (cpid == -1)
        {
            perror("fork");
            exit(EXIT_FAILURE);
        }

        if (cpid == 0)
        {
            /* Child reads from pipe */
            close(pipefd[i][1]); /* Close unused write end */
            range *rangePtr = malloc(sizeof(range));
            int sum = 0;

            while (read(pipefd[i][0], rangePtr, sizeof(range)) > 0)
            {
                int start = rangePtr->start;
                int end = rangePtr->end;
                for (int i = start; i <= end; i++)
                    sum += a[i];
            }

            write(pipefd[num_processes + i][1], &sum, sizeof(sum));
            close(pipefd[i][0]);
            close(pipefd[num_processes + i][1]);
            break;
        }
        else
        { /* Parent writes argv[1] to pipe */
            /* Close unused read end */
            range *rangePtr = malloc(sizeof(range));
            rangePtr->start = i * 10;
            rangePtr->end = i * 10 + 9;
            close(pipefd[i][0]);
            write(pipefd[i][1], rangePtr, sizeof(range));
            close(pipefd[num_processes + i][1]);
            close(pipefd[i][1]); /* Reader will see EOF */
            wait(NULL);          /* Wait for child */
            int sum;
            while (read(pipefd[num_processes + i][0], &sum, sizeof(sum)) > 0)
            {
                totalSum += sum;
            }

            close(pipefd[num_processes + i][0]);
            // write(STDOUT_FILENO, &totalSum, sizeof(totalSum));
        }
    }
    printf("%d\n", totalSum);

    _exit(EXIT_SUCCESS);
}

In the above I expected the value of totalSum variable which is outside of the for loop
to be printed exactly once. But I see

0
10
20
30
40
50
60
70
80
90
100

as the output. What could be the reason for that ?

Upvotes: 0

Views: 154

Answers (1)

Orielno
Orielno

Reputation: 409

Each of the child processes enters the if (cpid == 0) statement, and in its end there is break;, so the child process exits the loop and continues after the loop, i.e. it continues to the command printf("%d\n", totalSum);.

If you don't want that, just replace the break; with return 0;.

Upvotes: 1

Related Questions