/ / con respecto a la relación de close () y read () - c, process, pipe

Con respecto a la relación de close () y read () - c, process, pipe

int main()
{
char *msg="hello";
char buff[MAX];
int p[2];
pipe(p);
int i,pid=fork();
if(pid>0){
//close(p[1]);
read(p[0],buff, MAX);
}
else
{
printf("child exitingn");
}
}

¿Por qué el código anterior termina bloqueando? Pero entonces si quitamos el comentario y colocamos

close(p[1])

entonces ¿por qué el código termina inmediatamente?

Respuestas

2 para la respuesta № 1

Una vez que creas una tubería, obtiene cuatro extremos:

  • Un final de lectura p[0] en el proceso padre
  • Un final de escritura p[1] en el proceso padre
  • Un final de lectura p[0] en el proceso del niño
  • Un final de escritura p[1] en el proceso del niño

UNIX no entregará EOF para el lector, a menos que ambos extremos de escritura se hayan cerrado, porque sabe que la canalización aún se puede escribir.

Cuando sale el proceso hijo, cierra ambos extremos de la tubería de lado. Sin embargo, el padre todavía tiene un extremo abierto que se puede escribir, por lo que la lectura de los bloques de tuberías en lugar de entregar una EOF a los padres. Es por eso que el manual UNIX le indica que cierre los extremos no utilizados de la tubería de inmediato:

Una aplicación que utiliza pipe(2) y fork(2) debe usar adecuado close(2) llamadas para cerrar descriptores de archivos duplicados innecesarios; esto asegura que el final del archivo y SIGPIPE/EPIPE Se entregan cuando corresponda.

Aquí hay un ejemplo de cómo hacer que su programa no se bloquee sin cerrar p[1] en el lado de los padres:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* write_pipe(void* pp) {
int* p = (int*)pp;
char msg[] = "Hello from another thread!";
write(p[1], msg, sizeof(msg));
return NULL;
}

int main()
{
char buff[100];
int p[2];
pipe(p);
int pid=fork();
if(pid>0){
pthread_t thread1;
pthread_create (&thread1, NULL, &write_pipe, (void *)p);
read(p[0],buff, 100);
printf("%sn", buff);
printf("parent exitingn");
}
else
{
printf("child exitingn");
}
return 0;
}

El código de arriba escribe en el extremo de escritura delcanalizar desde un hilo dentro del proceso padre, en lugar de escribir desde el proceso hijo. Este es un uso legítimo de una tubería, también, que ilustra por qué UNIX no puede entregar EOF a menos que el extremo de escritura del padre de la tubería esté cerrado.


0 para la respuesta № 2

Leer es una llamada de bloqueo y se devuelve solo cuando recibe EOF. Si no cierra el extremo de escritura de la tubería, el final de lectura no obtendrá el EOF y, por lo tanto, el programa permanecerá bloqueado