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:
- Unix Programación avanzada, Fco. Manuel Márquez García