2012-09-28 54 views
3

我正在使用FIFO和select()系統命令運行測試。我們的想法是:無法理解select()系統調用

  1. 過程應該睡了select()命令等待從FIFO消息
  2. 如果沒有消息進來,過程應該喚醒每5秒鐘,說「沒事尚」
  3. 如果消息進來,它應該醒來,打印郵件,然後終止

因此,這裏的代碼注意我取出錯誤檢查,以節省空間:

//process 1's code 
int main() 
{ 
    int fd, ret; 
    fd_set rfds; 
    char buffer[100] = {0}; 
    char * myfifo = "/tmp/myfifo"; 
    struct timeval tv; 

    tv.tv_sec = 5; // 5 second sleep 
    tv.tv_usec = 0; 

    mkfifo(myfifo, 0666); //Make the fifo 

    fd = open(myfifo, O_RDONLY); 
    FD_ZERO(&rfds); // clear the flags 
    FD_SET(fd, &rfds); // set "read" on fd 

    while((ret = select(fd+1, &rfds, NULL, NULL, &tv)) <= 0) //should be 1 when we're ready to read 
    { 
    FD_ZERO(&rfds);  //I believe we should clear/reset these every time? 
    FD_SET(fd, &rfds); 
    printf("Nothing yet...%d\n",ret); 
    fflush(stdout); 
    } 
    n = read(fd, buffer, 100); 
    printf("I got a read of %d bytes\nIt was %s\n",n, buffer); 

    unlink(myfifo); 

    return 0; 
} 

曾經有過程1啓動並運行,我伺候好10秒,然後我開球過程中的兩個:

//Process 2's code 
int main() 
{ 
    int fd, n, ret; 
    fd_set rfds; 
    char buffer[100] = {0}; 
    char * myfifo = "/tmp/myfifo"; 
    fd = open(myfifo, O_WRONLY); 

    printf("What would you like to send?\n"); 
    fgets(buffer, 100, stdin); 
    write(fd, buffer, strlen(buffer)); 

    close(fd); 
    return 0; 
} 

我期待看到這樣的:

Nothing yet...0 
Nothing yet...0 
I got a read of X bytes 
It was <some string> 

相反,我沒有看到任何東西,直到我輸入了一些內容並按回車鍵輸入第二個進程,第一個進程才正確返回字符串......但爲什麼不是循環輸出消息?

+0

它打印「Nothing yet」一次嗎? – Serge

+0

@Serge - 不,它從不打印「Nothing yet」 – Mike

回答

3

由於您在Linux上,您可能希望將O_NONBLOCK添加到open()在閱讀器端的調用中。詳情請參閱man 7 fifo

+0

優秀點or'ing在NONBLOCK。這解決了它。 – Mike

6

人選擇:

在Linux上,選擇()修改超時反映的時間不 睡覺量;大多數其他實現不這樣做。 (POSIX.1-2001 允許任一行爲。)

因此,您應該在循環內重新初始化電視。但這不是你的問題的原因。原因是:

人mkfifo:

打開FIFO讀取正常阻塞,直到其他一些 進程打開的寫作相同的FIFO,反之亦然。

+1

也許值得一提的是如何解決這個問題(即在非阻塞模式下打開)。 – rici

+0

+1用於解決超時問題。 :) – Mike