Pipe malfunction, fork

2

I am studying how to make pipes to child processes; I wrote this test code that creates a series of children (4 in this example), and opens pipes between them and the parent process (at least I would like that):

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

int Prueba(int N);



int main()
{

    printf("%d\t",1); //Salida rara
    //printf("%d\n",1); //Salida "esperada"

    Prueba(4); 

    return 0;
}


int Prueba(int N)
{
    int i,j;
    int ind_hijo;
    int pid_padre, *pid_hijo, **tuberia;


    pid_hijo = (int*)malloc(sizeof(int)*N);
    tuberia = (int**)malloc(sizeof(int*)*N);
    tuberia = (int**)malloc(sizeof(int*)*N);

    for(i=0;i<N;i++)
        tuberia[i]=(int*)malloc(sizeof(int)*2);



    for(i=0;i<N;i++)
        pid_hijo[i]=-1;  //Inicializo el array de hijos

    pid_padre = getpid();


    for(i=0;i<N;i++)
    {

        if(getpid() == pid_padre) //El padre (y solo el padre) crea hijos
        {
            pipe(tuberia[i]); //Se abren dos descriptores de archivo por cada hijo que se va a crear
            pid_hijo[i]=fork(); //Se crea el i-esimo hijo
            if(pid_hijo[i] == 0)
            {
                pid_padre = -1; //De este modo se distingue a los hijos del padre rapidamente

                close(tuberia[i][0]); //Cada hijo cierra el extremo de lectura de su tubo...
            }
            close(tuberia[i][1]); //... y el padre cierra los extremos de escritura de sus tubos
        }
    }


    if(pid_padre == -1)
    {
        //... Codigo  ...

        exit(0); //se cierra cada proceso hijo
    }




    while(wait(NULL)>0); //El padre espera a que todos los hijos esten cerrados



    for(i=0;i<N;i++)
        close(tuberia[i][0]); //El padre cierra los descriptores de archivo abiertos (esto es necesario??)


    return 0;

}

The program itself does nothing, just create the children and then close them and write a symbol (a "1"). I expected that "1" would be written only once (and that's the way I write it with "\ n"). However, with the line

printf("%d\t",1);

It turns out that the output in the terminal is:

1    1    1    1    1

I have done tests with another number of children, and the output is always the number of children +1. I do not understand anything of what is happening here.

    
asked by Guillermo. D. S. 12.06.2018 в 12:13
source

1 answer

1

When you call fork a complete copy of the entire memory of the current process is made and the copy is assigned to the new process. This copy includes, how could it be otherwise, both the output buffer and the input buffer.

When you call printf the text does not immediately dump to the console but instead accumulates in the output buffer until an implicit or explicit call is made to fflush .

An example of implicit call to fflush is made when calling input functions type scanf :

printf("Hola, dime tu nombre: ");
scanf("%s,nombre);

In this case we will always see the message because scanf implicitly makes a call to fflush .

You can verify this end by forcing a call to fflush . Then you will see how the message appears only once:

printf("%d\t",1); //Salida rara
fflush(stdout);

Although, on the other hand, there are cleaner ways to print a 1 on the screen:

printf("1\t");

Or better yet

puts("1\t");
    
answered by 12.06.2018 / 12:39
source