BUG: el mensaje recibido para poder imprimirlo con printf debemos convertirlo en un string: string en C es un char array terminado en NUll (0x00) Podemos hacerlo de dos maneras: 1.- Escribir en el pipe 6 bytes en lugar de 5. El string "abcde" equivale a: {'a', 'b', 'c' ,'d', 'e', '\0'}. Cambiando el «5» por el «6» envío ese «0» final. write(fd[1], "abcde",6) 2. Tras leer del pipe añadir el cero de terminación en el buffer: buf[num] = 0x00; Nota: Aunque a mi me inprime printf bien, no tiene porqué ser así. El array buf no tiene porqué contener 0 en los bytes no escritos ya que no ha sido inicializado. Si ese fuera el caso printf inprimiría los 5 bytes y otros caracteres raros. Gracias a aquellos que me habéis indicado el error. Me centré en fork y pipe y olvidé este tema... es muy importante que un string termine en 0 y saber cuándo hay que ponerlo y que funciones precisan ese 0!!
Llevaba como 12 horas mirando libros en ingles y vídeos para un ejercicio de la Uni, pero no lo acababa de entender, con los 12 minutos de tu vídeo ya me aparece por pantalla el mensaje. Mil gracias!!!
Diosssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss !!!! La jefa, la sheriff de los "pipes". Explicado de una forma exquisita y entendible. Me has ahorrado semanas , jeje. Muchas gracias | Saludos :)
Gracias me suscribo, estoy estudiando c y estoy creando una shell básica, me ayudó mucho tu video para comenzar a entender todos estos conceptos, y me gusta tu voz.
Me ayudó mucho el video, lo que si, cuando escribes "abcde" estás escribiendo un String, por ende, tiene un '\0' al final lo que se traduce en que no lee 5 bytes sino que 6. Estuvo genial el video, gracias!!!
Holaa!! Si, cierto, "abcde" equivale a char buf[6]={'a', 'b', 'c', 'd', 'e','\0'}, yo escribo 5 de esos 6 caracteres y por eso después se leen 5 caracteres.
@@WhileTrueThenDream Lo he escrito como tiene usted (es decir, 5) y me entrega un caracter basura en la última posición; sin embargo, al poner 6 en la cantidad de chars leídos, me lo ha entregado correctamente (es decir, "abcde") Por si le sirve! gracias por el tutorial me ha ayudado mucho
Agradecido con el de arriba por haberme encontrado con estos vídeos. Estoy estudiando ing en sistemas y a pesar de que mi maestro de Operativos es bueno, mucha información la tengo que buscar jejeeje. Me agrado mucho la explicación de comunicación entre procesos. Like y un nuevo Suscriptor. c:
Hola. Me alegro, gracias por tu comentario. Los profes creo que a veces ponen las cosas dificiles para prepararnos para el trabajo, ahí es un constante learning by doing, leer foros de programación, manuales y aprender a fuerza de prueba y error
Sos muy genia. Video súper práctico y la explicación concisa :) Estoy cursando la materia Sistemas Operativos y tus videos me vienen como anillo al dedo je. Saludos desde Argentina!
Hola buen día. Actualmente estoy cursando la materia de Sistemas Operativos. Me gustaría que hicieras un video explicando el concepto de Memoria compartida. Realmente explicas muy bien. Saludos!!
Me encanto el video,muy pedagogico. Quiero consultar, es necesario cerra los extremos? tanto en la escritura como la lectura luego de que se envio el mensaje o puede quedar abierto?. O si fuese asi quedaria colgado el programa? SALUDOS y miles de gracias!
Hola Gracias. Una vez enviado el primer mensaje si cierras los extremos no podrás enviar mas mensajes, habría que volver a abrir el pipe. Si lo dejas abiertos puede seguir enviando mensajes. El pipe solo debe tener abierto un extremo de lectura y uno de escritura, de lo contrario no se leerán correctamente los bytes enviados. Si no los cierras, aal terminar los procesos se cerraran automaticamente los descriptores y los pipes. Saludos.
Gran video, pero me queda una duda. Cuando dices que los descriptores del padre se heredan al hijo, esto significa que se clonan dichos descriptores y por lo tanto, la tuberia al final tendría 4 descriptores en total?
Amaia si no pones la librería conio.h para que contenga la función sizeof(); puede que tal vez el programa no compile. Y la otra: si la variable de tipo entero no está inicializada después de declararla tendría basura. Aclaración: para la sentencia switch te falta el bucle do while..
Hola. Hace tiempo que grabé este vídeo, le echaré un ojo cuando tenga tiempo para chequear lo que me dices, aunque esa .h q mencionas no la necesitas, el operador "sizeof" es parte del lenguaje C. ¿Leíste en algùn lugar lo contrario? Saludos!
Hola Daniel. Respecto a la inicialización tenías razón, hay un error . Puse un comentario indicándolo. Gracias. Saludos, perdón por la tardanza de mi respuesta.
Hola. el video es genial. Tengo una unica duda. Como puedo hacer para que si quiero ejecutar un programa en el proceso hijo que escribe un char por la salida estandar, el padre lo recoja?
Hola, tengo una pregunta, ¿cómo le hago para comunicar 'n' tuberías? Tengo que desarrollar una minishell y tengo problema al ejecutar comandos del tipo 'ls | sort -n | wc | ... | ...', sé que tengo que crear tantas tuberías como comandos, pero no se como comunicar todas, además cada comando debe ser un proceso hijo y ejecutarlo con funciones exec(). Espero puedas ayudarme, gracias.
Nota: si el programa te retorna Padre lee 5 bytes: abcde��, inicialice la variable buf -> char buf[10] = ""; _ Esto ya que al establecerle un tamaño de 10, va a reservar dicho espacio en memoria y luego solo rescribe los primeros 5 bits, por ende los siguientes bits, son bites basura
Hola. Gracias por el comentario, voy a añadir una nota en el vídeo sobre el tema de «cero de terminación de un string» Aqui no traté el tema del cero de finalización de un string en C, aunque debería haberlo hecho. En realidad "abcde" son 6 bytes, ya que todo string en C tiene un cero de terminación. Podría haber enviado 6 bytes en lugar de 5 y habría recibido ese 0 y printf, que imprime hasta encontrar ese 0 de finalización, siempre escribiría valores validos. Tambien podria haber añadido ese cero de terminación tras leer del pipe. El tema es que printf necesita ese cero, y aqui el printf imprime bien ya que por casualidad tenia ese cero en la posicion 6. Si inicializas todo el array com cero, como tu dices, ese printf también imprimira bien tras leer. Si estamos constantemente leyendo del pipe es mas sencillo añadir el cero de terminacion que inicializar constantemente todo el array. Saludos
Muchas gracias por tu ayuda de verdad !!!. Quería preguntarte cómo sería la implementación de varios pipes (con varios procesos, usando dup2 y execl), ya que a la hora de cerrar descriptores de fichero no consigo que me funcione correctamente. Empiezo a hacer fork() y empieza a heredar ... y ya me pierdo.
Hola. Si saco mañana un rato lo miro. Qué quieres hacer exactamente? Comunicar dos procesos independientes con pipes? Communicar padre e hijo? Es un requerimiento el execl y el dup2?
@@WhileTrueThenDream pues saber comunicar 3 procesos en este caso. Ya sabiendo con 3 sabría creo que con más. Por ejemplo: ./pipeline 'ls -l /' 'grep u' 'wc -l' que sería el caso de: ls -l | grep u | wc -l, y la salida estándar sería el del último comando. Me exigen que sea con execv y que los ejecutables se busquen en /bin (2 primeros comandos) y /usr/bin (tercer comando) respectivamente. Muchas gracias de verdad 😌😌😌😌
@Fer Feuer Frei Freyja Hola. Tenía el tema de los pipes con fork ya oxidado :-S ... ahí te lo dejo.¿ De dónde ha salido este ejercicio, de la uni? Desde la carrera no veía un problema de este tipo ... Lo he probado un poco y funciona, si ves algo raro me dices. #include #include #include #include #include #include #define READ_END 0 /* index pipe extremo lectura */ #define WRITE_END 1 /* index pipe extremo escritura */ int main(int argc, char* argv[]) { int fd1[2],fd2[2]; int status, pid; pipe(fd1); /* comunica ls y grep */ pid = fork(); if(pid == 0) /* hijo 1*/ { close(fd1[READ_END]); /* cerrar extremo no necesario */ dup2(fd1[WRITE_END], STDOUT_FILENO); close(fd1[WRITE_END]); execlp("/bin/ls", "ls", "-l", NULL); } else /* padre */ { close(fd1[WRITE_END]); /* extremo no necesario ya */ pipe(fd2); /* comunica grep y wc */ pid = fork(); if(pid == 0) /* hijo 2 */ { close(fd2[READ_END]); /* cerrar extremo no necesario */ dup2(fd1[READ_END], STDIN_FILENO); close(fd1[READ_END]); dup2(fd2[WRITE_END], STDOUT_FILENO); close(fd2[WRITE_END]); execlp("/bin/grep","grep", "u",NULL); } else /* padre */ { close(fd1[READ_END]); /* cerrar extremo no necesario */ close(fd2[WRITE_END]); /* cerrar extremo no necesario */ pid = fork(); if(pid == 0) /* hijo 3*/ { dup2(fd2[READ_END], STDIN_FILENO); close(fd2[READ_END]); execlp("/usr/bin/wc","wc", "-l",NULL); } } } close(fd2[READ_END]); /* cerrar extremo que queda abierto en el padre */ /* wait para cada hijo */ wait(&status); wait(&status); wait(&status); return 0; }
@@WhileTrueThenDream joe ... muchas gracias !!!!!!!, para ver el desarrollo de los pipes me ha servido muchísimo !! pues el ejercicio es de la carrera sí. Así sí que me funciona ... pero me exigen que sea con 'execv' para que pueda realizarse con 3 procesos cualesquiera. Para tokenizar me recomiendan usar 'strtok_r'. Luego más tarde veré a ver si consigo hacerlo pero ayer me puse con él, ya entendiendo los cierres de los ficheros, pero nada, que no sale ..... 😌😌
Omg que complicado, eso es en una practica o es en plan proyecto de fin de asignatura? A nosotros en la carrera como mucho nos pedian un pipe pa comunicar dos comandos,. El strok no lo he usado nunca. No tengo tiempo, pero la curiosidad me mata...jejejje. le echaré un ojo por la noche.
@@WhileTrueThenDream "La definición de "unión" es similar a la de "estructura", La diferencia entre las dos es que en una estructura, los miembros ocupan diferentes áreas de la memoria, pero en una unión, los miembros ocupan la misma área de memoria. ".... Encontré esa definición en wiki.....
Si el padre quiere escribir/enviar un mensaje en el pipe para que lo pueda leer el hijo, pero el hijo lo lee cuando el padre aún no lo ha escrito/enviado, entonces el hijo se bloquea? Saludos.
BUG:
el mensaje recibido para poder imprimirlo con printf debemos convertirlo en un string:
string en C es un char array terminado en NUll (0x00)
Podemos hacerlo de dos maneras:
1.- Escribir en el pipe 6 bytes en lugar de 5. El string "abcde" equivale a: {'a', 'b', 'c' ,'d', 'e', '\0'}. Cambiando el «5» por el «6» envío ese «0» final.
write(fd[1], "abcde",6)
2. Tras leer del pipe añadir el cero de terminación en el buffer: buf[num] = 0x00;
Nota:
Aunque a mi me inprime printf bien, no tiene porqué ser así. El array buf no tiene porqué contener 0 en los bytes no escritos ya que no ha sido inicializado. Si ese fuera el caso printf inprimiría los 5 bytes y otros caracteres raros.
Gracias a aquellos que me habéis indicado el error. Me centré en fork y pipe y olvidé este tema... es muy importante que un string termine en 0 y saber cuándo hay que ponerlo y que funciones precisan ese 0!!
Wow ojalá hubiera tenido una profesora que explicara así . Pd: tu voz es tan agradable y relajante que creo que también la utilizaré para dormir 😴
Hola! ahora veo tu mensaje, las notificiaciones no las recibo. Graacias. jajaj, aburro tanto que los vídeos sirven para dormir! ;-P .
@@WhileTrueThenDream Mas vale tarde que nunca! jajaja y para nada aburres .Tu contenido me parece muy interesante .
Un año después, el video me funciona para aprender más sobre el Lenguaje C. Tu voz es muy relajante
Llevaba como 12 horas mirando libros en ingles y vídeos para un ejercicio de la Uni, pero no lo acababa de entender, con los 12 minutos de tu vídeo ya me aparece por pantalla el mensaje. Mil gracias!!!
Muchas gracias. :-)
De aprender ingles no nos libramos... casi todo el material bueno se encuentra en ingles.
@@WhileTrueThenDream El problema no era el idioma, era encontrar alguien que lo explicara bien ;)
Diosssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss !!!! La jefa, la sheriff de los "pipes". Explicado de una forma exquisita y entendible. Me has ahorrado semanas , jeje. Muchas gracias | Saludos :)
Gracias me suscribo, estoy estudiando c y estoy creando una shell básica, me ayudó mucho tu video para comenzar a entender todos estos conceptos, y me gusta tu voz.
Muchas gracias por el vídeo, planteas de forma sencilla algo que a algunos/as les cuesta horas en clase.
Muchas gracias por la explicación tan clara, la verdad es que tu canal tiene un valor tremendo!
Me ayudó mucho el video, lo que si, cuando escribes "abcde" estás escribiendo un String, por ende, tiene un '\0' al final lo que se traduce en que no lee 5 bytes sino que 6. Estuvo genial el video, gracias!!!
Holaa!!
Si, cierto, "abcde" equivale a char buf[6]={'a', 'b', 'c', 'd', 'e','\0'}, yo escribo 5 de esos 6 caracteres y por eso después se leen 5 caracteres.
@@WhileTrueThenDream Lo he escrito como tiene usted (es decir, 5) y me entrega un caracter basura en la última posición; sin embargo, al poner 6 en la cantidad de chars leídos, me lo ha entregado correctamente (es decir, "abcde")
Por si le sirve! gracias por el tutorial me ha ayudado mucho
Gracias, lo miraré. El video es de hace unos meses y no recuerdo qué hacía
Hola de nuevo! Lo revisé, perdón por la tardanza. Tenias toda la razón. Puse un comentario indicando el bug y su corrección. Saludos
Eres increible, gracias a ti terminé mi deber en menos de 20 minutos !
Agradecido con el de arriba por haberme encontrado con estos vídeos. Estoy estudiando ing en sistemas y a pesar de que mi maestro de Operativos es bueno, mucha información la tengo que buscar jejeeje.
Me agrado mucho la explicación de comunicación entre procesos. Like y un nuevo Suscriptor. c:
Hola.
Me alegro, gracias por tu comentario. Los profes creo que a veces ponen las cosas dificiles para prepararnos para el trabajo, ahí es un constante learning by doing, leer foros de programación, manuales y aprender a fuerza de prueba y error
Sos muy genia. Video súper práctico y la explicación concisa :) Estoy cursando la materia Sistemas Operativos y tus videos me vienen como anillo al dedo je. Saludos desde Argentina!
jaja que loco te vi en la lista de correos de mendez. Vimos el mismo video
jajajajajaj aguante
Muy genial!!! Gracias, considero que soy de aprendizaje lento y hay pocos videos como los tuyos sobre este tema
Quiero agradecerte por la explicación..
Practica, clara.
Como quien dice, cortita y al pie... Jeje
Hola buen día. Actualmente estoy cursando la materia de Sistemas Operativos. Me gustaría que hicieras un video explicando el concepto de Memoria compartida. Realmente explicas muy bien. Saludos!!
Hola! Me gustaría hacerlo, aunque no puedo prometer que sea en breve
@@WhileTrueThenDream Sí, no te preocupes. Muchas gracias :)
salvaste mi proyecto de sistemas operativos, muchas gracias.
Excelente, muy instructivo. Gracias.
Me encanto el video,muy pedagogico. Quiero consultar, es necesario cerra los extremos? tanto en la escritura como la lectura luego de que se envio el mensaje o puede quedar abierto?. O si fuese asi quedaria colgado el programa? SALUDOS y miles de gracias!
Hola
Gracias.
Una vez enviado el primer mensaje si cierras los extremos no podrás enviar mas mensajes, habría que volver a abrir el pipe. Si lo dejas abiertos puede seguir enviando mensajes. El pipe solo debe tener abierto un extremo de lectura y uno de escritura, de lo contrario no se leerán correctamente los bytes enviados. Si no los cierras, aal terminar los procesos se cerraran automaticamente los descriptores y los pipes.
Saludos.
@@WhileTrueThenDream Muchas gracias me terminó de quedar muy claro. Saludos!!!
Me encanta! muchas gracias por tu aportación!
Tremenda explicación, bien clarito
Gran video, pero me queda una duda. Cuando dices que los descriptores del padre se heredan al hijo, esto significa que se clonan dichos descriptores y por lo tanto, la tuberia al final tendría 4 descriptores en total?
Amaia si no pones la librería conio.h para que contenga la función sizeof(); puede que tal vez el programa no compile.
Y la otra: si la variable de tipo entero no está inicializada después de declararla tendría basura.
Aclaración: para la sentencia switch te falta el bucle do while..
Hola.
Hace tiempo que grabé este vídeo, le echaré un ojo cuando tenga tiempo para chequear lo que me dices, aunque esa .h q mencionas no la necesitas, el operador "sizeof" es parte del lenguaje C. ¿Leíste en algùn lugar lo contrario?
Saludos!
Hola Daniel.
Respecto a la inicialización tenías razón, hay un error . Puse un comentario indicándolo. Gracias. Saludos, perdón por la tardanza de mi respuesta.
A una hora del examen... mil gracias!!!
Buen contenido. Felicitaciones....!
En mi universidad no enseñan pipes :c se ve interesante
Hola. el video es genial. Tengo una unica duda.
Como puedo hacer para que si quiero ejecutar un programa en el proceso hijo que escribe un char por la salida estandar, el padre lo recoja?
Qué genial
Hola. Te consulto: teniendo los sockets a disposición, los pipes siguen siendo rentables para comunicar procesos?
Slds
Gracias por otra video genial.
vaya buen video!!!
:)
Hola, tengo una pregunta, ¿cómo le hago para comunicar 'n' tuberías?
Tengo que desarrollar una minishell y tengo problema al ejecutar comandos del tipo 'ls | sort -n | wc | ... | ...', sé que tengo que crear tantas tuberías como comandos, pero no se como comunicar todas, además cada comando debe ser un proceso hijo y ejecutarlo con funciones exec().
Espero puedas ayudarme, gracias.
Hola.
Hace poco subì un video que te puede ayudar, comunica dos o tres comandos, mira los más actuales.
Saludos
holaaa porque no se me ejecuta el programa ya hice lo que dicen pero no vale. Ayudaa
como hago para pasar un numero float por la tuberia?
Hola.
En el foro Stack overflow tienes ejemplos. Puedes googlear "pipe send floating points values stack overflow "
Saludos
Nota: si el programa te retorna Padre lee 5 bytes: abcde��, inicialice la variable buf -> char buf[10] = "";
_ Esto ya que al establecerle un tamaño de 10, va a reservar dicho espacio en memoria y luego solo rescribe los primeros 5 bits, por ende los siguientes bits, son bites basura
Hola.
Gracias por el comentario, voy a añadir una nota en el vídeo sobre el tema de «cero de terminación de un string»
Aqui no traté el tema del cero de finalización de un string en C, aunque debería haberlo hecho. En realidad "abcde" son 6 bytes, ya que todo string en C tiene un cero de terminación.
Podría haber enviado 6 bytes en lugar de 5 y habría recibido ese 0 y printf, que imprime hasta encontrar ese 0 de finalización, siempre escribiría valores validos. Tambien podria haber añadido ese cero de terminación tras leer del pipe.
El tema es que printf necesita ese cero, y aqui el printf imprime bien ya que por casualidad tenia ese cero en la posicion 6. Si inicializas todo el array com cero, como tu dices, ese printf también imprimira bien tras leer. Si estamos constantemente leyendo del pipe es mas sencillo añadir el cero de terminacion que inicializar constantemente todo el array.
Saludos
Muchas gracias por tu ayuda de verdad !!!. Quería preguntarte cómo sería la implementación de varios pipes (con varios procesos, usando dup2 y execl), ya que a la hora de cerrar descriptores de fichero no consigo que me funcione correctamente. Empiezo a hacer fork() y empieza a heredar ... y ya me pierdo.
Hola.
Si saco mañana un rato lo miro. Qué quieres hacer exactamente? Comunicar dos procesos independientes con pipes? Communicar padre e hijo?
Es un requerimiento el execl y el dup2?
@@WhileTrueThenDream pues saber comunicar 3 procesos en este caso. Ya sabiendo con 3 sabría creo que con más. Por ejemplo: ./pipeline 'ls -l /' 'grep u' 'wc -l' que sería el caso de: ls -l | grep u | wc -l, y la salida estándar sería el del último comando. Me exigen que sea con execv y que los ejecutables se busquen en /bin (2 primeros comandos) y /usr/bin (tercer comando) respectivamente. Muchas gracias de verdad 😌😌😌😌
@Fer Feuer Frei Freyja Hola. Tenía el tema de los pipes con fork ya oxidado :-S ... ahí te lo dejo.¿ De dónde ha salido este ejercicio, de la uni? Desde la carrera no veía un problema de este tipo ... Lo he probado un poco y funciona, si ves algo raro me dices.
#include
#include
#include
#include
#include
#include
#define READ_END 0 /* index pipe extremo lectura */
#define WRITE_END 1 /* index pipe extremo escritura */
int main(int argc, char* argv[])
{
int fd1[2],fd2[2];
int status, pid;
pipe(fd1); /* comunica ls y grep */
pid = fork();
if(pid == 0) /* hijo 1*/
{
close(fd1[READ_END]); /* cerrar extremo no necesario */
dup2(fd1[WRITE_END], STDOUT_FILENO);
close(fd1[WRITE_END]);
execlp("/bin/ls", "ls", "-l", NULL);
}
else /* padre */
{
close(fd1[WRITE_END]); /* extremo no necesario ya */
pipe(fd2); /* comunica grep y wc */
pid = fork();
if(pid == 0) /* hijo 2 */
{
close(fd2[READ_END]); /* cerrar extremo no necesario */
dup2(fd1[READ_END], STDIN_FILENO);
close(fd1[READ_END]);
dup2(fd2[WRITE_END], STDOUT_FILENO);
close(fd2[WRITE_END]);
execlp("/bin/grep","grep", "u",NULL);
}
else /* padre */
{
close(fd1[READ_END]); /* cerrar extremo no necesario */
close(fd2[WRITE_END]); /* cerrar extremo no necesario */
pid = fork();
if(pid == 0) /* hijo 3*/
{
dup2(fd2[READ_END], STDIN_FILENO);
close(fd2[READ_END]);
execlp("/usr/bin/wc","wc", "-l",NULL);
}
}
}
close(fd2[READ_END]); /* cerrar extremo que queda abierto en el padre */
/* wait para cada hijo */
wait(&status);
wait(&status);
wait(&status);
return 0;
}
@@WhileTrueThenDream joe ... muchas gracias !!!!!!!, para ver el desarrollo de los pipes me ha servido muchísimo !! pues el ejercicio es de la carrera sí. Así sí que me funciona ... pero me exigen que sea con 'execv' para que pueda realizarse con 3 procesos cualesquiera. Para tokenizar me recomiendan usar 'strtok_r'. Luego más tarde veré a ver si consigo hacerlo pero ayer me puse con él, ya entendiendo los cierres de los ficheros, pero nada, que no sale ..... 😌😌
Omg que complicado, eso es en una practica o es en plan proyecto de fin de asignatura? A nosotros en la carrera como mucho nos pedian un pipe pa comunicar dos comandos,. El strok no lo he usado nunca. No tengo tiempo, pero la curiosidad me mata...jejejje. le echaré un ojo por la noche.
Excellent... Tenes videos de union?
Hola! No tengo... por "unión" te refieres al data type?
@@WhileTrueThenDream "La definición de "unión" es similar a la de "estructura", La diferencia entre las dos es que en una estructura, los miembros ocupan diferentes áreas de la memoria, pero en una unión, los miembros ocupan la misma área de memoria. ".... Encontré esa definición en wiki.....
entonces esto es como crear threads?
Hola.
Con fork creas un nuevo proceso.
Un pipe es un mecanismo de comunicación entre procesos.
Un thread es un hilo, no un proceso.
Saludos
@@WhileTrueThenDream Gracias por la aclaracion
Si el padre quiere escribir/enviar un mensaje en el pipe para que lo pueda leer el hijo, pero el hijo lo lee cuando el padre aún no lo ha escrito/enviado, entonces el hijo se bloquea?
Saludos.
Hola,
La operación de lectura es bloqueante a no ser que se haya especificado el Flag O_NONBLOCK al abrir el pipe.
Saludos
@@WhileTrueThenDream vale, gracias por la duda preciosa
Facil