2012-08-10 7 views
8

Este es el ejemplo de código de "man select" más algunas líneas para leer un archivo real que se está escribiendo. Sospeché que cuando se escribe el ./myfile.txt, select devolvería que ahora puede leer desde ese fd. Pero lo que ocurre es que select regresa constantemente en el ciclo while mientras exista el archivo txt. Quiero que solo regrese cuando se escriben nuevos datos al final del archivo. Pensé que así es como debería funcionar.¿Cómo puede select() esperar en los descriptores de archivos regulares (no sockets)?

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

int 
main(void) 
{ 
    fd_set rfds; 
    struct timeval tv; 
    int retval; 

    int fd_file = open("/home/myfile.txt", O_RDONLY); 

    /* Watch stdin (fd 0) to see when it has input. */ 
    FD_ZERO(&rfds); 
    FD_SET(0, &rfds); 
    FD_SET(fd_file, &rfds); 

    /* Wait up to five seconds. */ 
    tv.tv_sec = 5; 
    tv.tv_usec = 0; 

    while (1) 
    { 
    retval = select(fd_file+1, &rfds, NULL, NULL, &tv); 
    /* Don't rely on the value of tv now! */ 

    if (retval == -1) 
     perror("select()"); 
    else if (retval) 
     printf("Data is available now.\n"); 
     /* FD_ISSET(0, &rfds) will be true. */ 
    else 
     printf("No data within five seconds.\n"); 
    } 

    exit(EXIT_SUCCESS); 
} 
+0

¿Cuál es su pregunta? ** ¿Quién dijo que 'select' solo debería funcionar en sockets **? – cnicutar

+0

pregunta editada. perdon por la confusion. – glutz

+0

'select' se puede usar en _ cualquier_ descriptor de tipo de archivo, no importa si es un socket, archivo o pipe o cualquier otro descriptor similar. Sin embargo, no puede usarlo para monitorear cuándo se ha escrito un archivo, para eso debe usar algo específico del SO, como en Linux puede usar [inotify] (http://en.wikipedia.org/wiki/Inotify) –

Respuesta

13

archivos de disco son siempre listo para leer (pero la lectura podrían volver 0 bytes si ya está al final del archivo), por lo que no se puede utilizar select() en un archivo de disco para averiguar cuándo nuevos datos se agregan al archivo.

POSIX dice: descriptores

archivos asociados a los archivos regulares siempre seleccionarán cierto para prepararse para leer, listo para escribir, y las condiciones de error.

También, como cnicutar señalado en un post-ahora eliminado, en general, tiene que inicializar el FD_SET en cada iteración. En su código, está monitoreando un fd, y ese fd siempre está listo, por lo que el FD_SET en realidad no está cambiando. Sin embargo, si tiene 5 descriptores para monitorear, y select detecta que solo uno está listo, en la siguiente iteración solo se monitoreará ese descriptor (a menos que restablezca el FD_SET). Esto hace que usar select sea complicado.

+1

esto parece ser correcto según mis pruebas. maldito. – glutz

Cuestiones relacionadas