Search code examples
cpipefork

the pipes don"t send the tab


In my code, i have to use several pipes, the father must send each sons an interval, and in this interval the son must search prime numbers.

the problem is that the interval sent by the father is not received by the sons. this is my code :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>

int main(void)
{
    const int p = 4;
    const int n = 500;

    int k, i, j;
    int premier;

    pid_t fils[p];
    int tubePere[2], tubeFils[p][2], intervals1[2], intervals2[2];

    pipe(tubePere);
    for (k = 0; k < p; k++)
    {
        pipe(tubeFils[p]);
        fils[k] = fork();
        intervals1[0] = k * n/p + 1;
        intervals1[1] = (k + 1) * n/p;
        printf("intervals1 : %d .. %d\n",intervals1[0], intervals1[1]);
        close(tubeFils[k][0]);
        write(tubeFils[k][1], intervals1, sizeof(intervals1));
        if (fils[k] == 0)
        {
            close(tubeFils[k][1]);
            read(tubeFils[k][0],  intervals2, sizeof(intervals2));
            printf("intervals2 : %d .. %d\n",intervals2[0], intervals2[1]);
            for (i = intervals1[0]; i <= intervals2[1]; i++)
            {
                if (i == 1)
                    premier = 0;
                else if (i == 2)
                    premier = 1;
                else
                {
                    j = 2;
                    premier = 1;
                    while ((j <= sqrt(i)) && (premier == 1))
                    {
                        if ((i%j) == 0)
                            premier = 0;
                        j++;
                    }
                }
                if (premier == 1)
                {
                   //printf("%d  ",i);
                }
            }
            exit(0);

        }
        else if (fils[k] == -1)
            printf("Error\n");
    }
    return 0;
}

I displayed the intervals received by the sons and send by the father

intervals1 : 1 .. 125
intervals1 : 126 .. 250
intervals1 : 251 .. 375
intervals1 : 376 .. 500
intervals1 : 1 .. 125
intervals1 : 126 .. 250
intervals1 : 251 .. 375
intervals1 : 376 .. 500
intervals2 : 0 .. 255
intervals1 : 1 .. 125
intervals1 : 126 .. 250
intervals1 : 251 .. 375
intervals2 : 0 .. 255
intervals1 : 1 .. 125
intervals1 : 126 .. 250
intervals2 : 0 .. 255
intervals1 : 1 .. 125
intervals2 : 0 .. 255

Solution

  • You are doing the pere write in both pere and fil instead of only in pere.

    Your second pipe call is pipe(tubefils[p]) but it needs to be pipe(tubefils[k])

    You should do wait at the end of pere.

    And, you should close the write end of the pipe in the parent after doing the write.

    And, you should close the read end of the pipe in the child after doing the read.


    Here's some corrected code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <math.h>
    #include <sys/wait.h>
    
    int
    main(void)
    {
        const int p = 4;
        const int n = 500;
    
        int k, i, j;
        int premier;
    
        pid_t pid;
        pid_t fils[p];
        int tubePere[2], tubeFils[p][2], intervals1[2], intervals2[2];
    
        pipe(tubePere);
        for (k = 0; k < p; k++) {
    #if 0
            pipe(tubeFils[p]);
    #else
            pipe(tubeFils[k]);
    #endif
    
            pid = fork();
            fils[k] = pid;
    
            if (pid < 0) {
                printf("Error\n");
                exit(1);
            }
    
            // pere ...
            if (pid != 0) {
                intervals1[0] = k * n / p + 1;
                intervals1[1] = (k + 1) * n / p;
                printf("intervals1 : %d .. %d\n", intervals1[0], intervals1[1]);
                close(tubeFils[k][0]);
                write(tubeFils[k][1], intervals1, sizeof(intervals1));
                close(tubeFils[k][0]);
                continue;
            }
    
            // fils ...
            close(tubeFils[k][1]);
            read(tubeFils[k][0], intervals2, sizeof(intervals2));
            close(tubeFils[k][0]);
    
            printf("intervals2 : %d .. %d\n", intervals2[0], intervals2[1]);
    
            for (i = intervals1[0]; i <= intervals2[1]; i++) {
                if (i == 1)
                    premier = 0;
                else if (i == 2)
                    premier = 1;
                else {
                    j = 2;
                    premier = 1;
                    while ((j <= sqrt(i)) && (premier == 1)) {
                        if ((i % j) == 0)
                            premier = 0;
                        j++;
                    }
                }
                if (premier == 1) {
                    // printf("%d ",i);
                }
            }
            exit(0);
        }
    
        while (1) {
            pid = wait(NULL);
            if (pid <= 0)
                break;
        }
        return 0;
    }
    

    Here's the corrected output:

    intervals2 : 1 .. 125
    intervals1 : 1 .. 125
    intervals2 : 126 .. 250
    intervals1 : 1 .. 125
    intervals1 : 126 .. 250
    intervals1 : 251 .. 375
    intervals2 : 376 .. 500
    intervals1 : 1 .. 125
    intervals1 : 126 .. 250
    intervals2 : 251 .. 375
    intervals1 : 1 .. 125
    intervals1 : 126 .. 250
    intervals1 : 251 .. 375
    intervals1 : 376 .. 500