Mecanismos de comunicación entre procesos (IV)

por | abril 15, 2014

Pipes

El tercer mecanismo IPC que vamos a tratar en esta saga son las tuberías (Pipes) y cuya principal característica es que son unidireccionales. Tal y como hace el shell en una orden del estilo ls | grep txt, el proceso a la izquierda de ‘|’ escribe en la tubería y el proceso de la derecha, lee.

Para hacer un uso correcto de las tuberías, debemos saber y comprender el funcionamiento  de los descriptores de archivo en el mundo Unix y, en particular, Linux (haremos uso de las funciones pipe y close).

Un ejemplo clásico de uso en programación de este tipo de IPC es cuando tenemos que desarrollar una aplicación que necesita comunicar a un padre con sus procesos hijos (o threads diferentes):

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
 
#define SIZE 1024
 
int main( int argc, char **argv )
{
    pid_t pid;
    int p[2], readbytes;
    char msg[SIZE];
    int state, i=0;
    pipe(p);
    if ( (pid=fork()) == 0 ){ 
      /* Child process*/
      /* First: We close pipe write side*/
      close(p[1]);
      while((readbytes=read(p[0], msg, SIZE)) > 0)
       /* We write it in stdout*/
          write(1, msg, readbytes);
      close(p[0]);
    }
    else {
        /* Father proccess*/
        /* Firts: We close pipe read side*/
        close(p[0]); 
        while (i<10) {
            sprintf(msg, "Message number %dn", i);
            write(p[1], msg, strlen(msg));
            i++;
        }
        close(p[1]);
        wait(&state);
    }
    exit(0);
}

Las funciones importantes del ejemplo son:

  • pipe: Crea la tubería. Necesita un vector de 2 elementos de enteros. El primero (posición 0) será la salida de la tubería (lectura) y el segundo, la entrada (escritura)
  • close: Cierra los descriptores que no vamos a usar. La lectura en el proceso que escriba y la escritura en el que lea. Además, cuando los procesos terminan, cierran los descriptores abiertos.
  • read y write: usadas para leer y escribir tomando como argumentos los descriptores de archivo apropiados (exactamente igual que haríamos con cualquier fichero)

 Referencias:

  1. Unix Programación avanzada, Fco. Manuel Márquez García