2015-08-28 64 views
1

下面是一個簡單的選擇()循環:混淆選擇() - 標準輸出從未準備好寫

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/select.h> 

#define BUFSIZE 999 

int main() 
{ 
    int   select_result; 
    fd_set   read_fds, write_fds; 
    struct timeval timeout = {0, 400000}, timeoutcopy; 
    const int max_fd = STDIN_FILENO > STDOUT_FILENO ? STDIN_FILENO : 
                 STDOUT_FILENO; 
    char buffer[BUFSIZE]; 

    fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK); 
    fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL) | O_NONBLOCK); 
    printf("Enter loop\n"); 
    while(1) { 
     FD_ZERO(&read_fds); 
     FD_ZERO(&write_fds); 
     printf("Loop\n"); 
     FD_SET(STDIN_FILENO, &read_fds); 
     FD_SET(STDOUT_FILENO, &write_fds); 

     timeoutcopy = timeout; 
     if ((select_result = select(max_fd, &read_fds, &write_fds, NULL, 
            &timeoutcopy)) < 0) { 
      return select_result; 
     } 

     if (FD_ISSET(STDIN_FILENO, &read_fds)) 
      printf("Stdin ready for read\n"); 
      fgets(buffer, BUFSIZE, stdin); 
      if (strlen(buffer)) 
       printf("Stdin content: %s\n", buffer); 
     if (FD_ISSET(STDOUT_FILENO, &write_fds)) 
      printf("Stdout ready for write\n"); 
    } 
} 

它只是投票stdinstdoutselect()與400000毫秒超時。當stdin準備就緒時,它會嘗試讀取它的內容並打印出來。當stdout準備就緒時,它只是打印,準備就緒。

由於某種原因,select()致電stdin之後從未準備好,爲什麼?

+2

在複製的代碼,你有沒有錯過括號'{...}''之後如果(FD_ISSET(STDIN_FILENO,與read_fds))'...正如所寫的,它會總是運行'fgets()',這樣(我認爲)沒有/很少機會輸入字符來準備好stdin。 – TripeHound

回答

2

您的max_fd應該是「三個集合中任何一箇中編號最高的文件描述符,加上1」。根據選擇手冊頁。我應該重新命名它,以便您記得添加1.

0

max_fd必須加1。名稱確實令人困惑,「nfds」可能更清晰。請看看這裏:

select man page