2010-08-12 15 views
9

Tengo el siguiente fragmento de código C, que se lee de un tubo y luego debería bloquear pero nunca bloquesno lee bloqueo en nombre de tubería

int pipe_fd; 
int res; 
int open_mode = O_RDONLY; 
char buf[100]; 
int bytes_read = 0; 

memset (buf, '\0', sizeof(buf)); 
pipe_fd = open(FIFO_NAME, open_mode); 

if (access(FIFO_NAME, F_OK) == -1) 
{ 
    res = mkfifo(FIFO_NAME, 0777); 
    if (res != 0) 
    { 
      fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME); 
      exit (EXIT_FAILURE); 
    } 
} 

for(;;) 
{   
    do  
    {  
     res = read(pipe_fd, buf, sizeof(buf)); 
     bytes_read += res; 
    }while (res > 0); 

    // process data then go back and block 
    ............ 
} 

Se envía un buffer sencilla por cierto código en un script bash así' ./test 1'

#!/bin/bash 

pipe=/tmp/pipe 

if [[ ! -p $pipe ]]; then 
    echo "Reader not running" 
    exit 1 
fi 

if [[ "$1" ]]; then 
    echo "some string" >$pipe 
else 
    echo "q" >$pipe 
fi 

que ejecutar el programa de código C en el BGF y en un principio lo hace en el bloque de lectura, pero tan pronto como me llamo la escritura del golpe sin el código C bloques más largos, lo hace con éxito lea los datos de el búfer y luego cada vez que lea hay 0 bytes leídos así que no estoy seguro de por qué ya no está bloqueando. Los datos de 'algunas cadenas' se reciben correctamente en el otro lado.

Sólo necesito que se siente allí esperando para el proceso de datos y luego ir a esperar a más

Respuesta

14

que ejecutar el programa de código C en el BGF y en un principio lo hace el bloque en la lectura, pero tan pronto como sea llamo al script bash que el código C ya no bloquea, lee con éxito los datos del búfer y cada vez que lee hay 0 bytes leídos, por lo que no estoy seguro de por qué ya no está bloqueando. Los datos de 'algunas cadenas' se reciben correctamente en el otro lado.

0 significa EOF. FIFO puede leerse o escribirse solo cuando hay procesos conectados a él tanto para leer como para escribir. Cuando no hay más escritores (los guiones del intérprete de comandos terminados) los lectores reciben una notificación al respecto a través del read() que devuelve el EOF.

FIFO se comportan de esa manera para que sea compatible con la lógica tubería cáscara ej .:

$ mkfifo ./tmp1 
$ cat <input> ./tmp1 & 
$ cat <./tmp1> /dev/null 

Si read() no volverá EOF, la segunda cat bloquearía para siempre.

Sólo necesito que se siente allí esperando para el proceso de datos y luego volver atrás y esperar más

En el programa de C que tiene que volver open() la FIFO después read() regresaron primera vez EOF .

P.S. Encontrado quite nice FIFO summary para su. Verifique la tabla en la segunda página.

+0

muchas gracias, no me di cuenta. ¿Debo cerrar el fifo después de recibir EOF antes de reabrirlo? – tech74

+0

@ tech74: Obviamente. 'open()' asigna un nuevo descriptor de archivo - el anterior tiene que ser liberado usando 'close()'. Los escritores también bloquearán hasta que vuelvas a abrir FIFO para leer nuevamente. – Dummy00001

+1

+1 para el enlace! –

0

su escritura del golpe se cierra el tubo por lo que el C es conseguir un "EF" condición

0

pienso escribir shell script lateral cerrar el tubo cada vez que algo de eco.

Por lo tanto, el script de escritura debe abrir el conducto y usar repetidamente el descriptor abierto para escribir algo y cerrar finalmente el descriptor abierto.

Cuestiones relacionadas