2012-08-10 138 views
8

這是「man select」的代碼示例以及幾行讀取正在寫入的實際文件的代碼示例。我懷疑當./myfile.txt被寫入時,select會返回,它現在可以從該fd讀取。但是會發生什麼,只要txt文件存在,select會不斷在while循環中返回。我希望它只在新數據寫入文件末尾時纔會返回。我認爲這是它應該如何工作。select()如何等待常規文件描述符(非套接字)?

#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

那麼你的問題是什麼? **誰說'select'只能在套接字上工作**? – cnicutar 2012-08-10 12:45:05

+0

編輯的問題。對於混淆抱歉。 – glutz 2012-08-10 12:49:44

+0

'select'可以在_any_文件類型描述符上使用,不管它是套接字,文件還是管道還是任何類似的描述符。然而,你不能用它來監視一個文件的寫入時間,因爲你必須使用一些特定的操作系統,比如你可以在Linux上使用[inotify](http://en.wikipedia.org/wiki/Inotify )。 – 2012-08-10 12:51:49

回答

13

磁盤文件隨時讀取(但如果你在文件的結尾是已經讀取可能會返回0字節),所以你不能使用select()在磁盤文件找出來的時候新的數據被添加到文件中。

POSIX說:與普通文件關聯

文件描述符應始終選擇準備好讀,準備寫,和錯誤條件真。

此外,作爲cnicutar在現在缺失後指出,在一般情況下,你必須初始化FD_SET在每次迭代。在你的代碼中,你正在監視一個fd,並且這個fd總是準備好,所以FD_SET實際上並沒有改變。但是,如果有5個描述符要監視,並且select檢測到只有一個準備就緒,那麼在下一次迭代時,只會監視一個描述符(除非您重置FD_SET)。這使得使用select棘手。

+1

根據我的測試,這似乎是正確的。織補。 – glutz 2012-08-10 13:02:11

相關問題