System-Calls

選擇系統呼叫的第一個參數的目的是什麼?

  • February 21, 2011

man select

int select(int nfds, fd_set *readfds, fd_set *writefds,
          fd_set *exceptfds, struct timeval *timeout);

nfds 是三組中編號最高的文件描述符,加 1。

nfds當我們已經有了和時readfds,可以從中確定文件描述符的目的是什麼?writefds``exceptfds

“UNIX 環境中的高級程式”中,W. Richard Stevens 說這是一種性能優化:

通過指定我們感興趣的最高描述符,核心可以避免遍曆三個描述符集中的數百個未使用位,尋找打開的位。

(第 1 版,第 399 頁)

如果您正在做任何類型的 UNIX 系統程式,強烈推薦 APUE 書。


更新

Anfd_set通常能夠跟踪多達 1024 個文件描述符。

fds跟踪哪些設置0和哪些設置的最有效方法是位集1,因此每個fd_set都包含 1024 位。

在 32 位系統上,long int(或“字”)是 32 位,這意味著每個fd_set

1024 / 32 = 32 個字。

如果nfds是一些小的東西,例如 8 或 16,在許多應用程序中都會出現,它只需要查看第一個單詞,這顯然比查看所有 32 個單詞要快。

(查看FD_SETSIZE__NFDBITS來自/usr/include/sys/select.h您平台上的值。)


更新 2

至於為什麼函式簽名不是

int select(fd_set *readfds, int nreadfds,
          fd_set *writefds, int nwritefds,
          fd_set *exceptfds, int nexceptfds,
          struct timeval *timeout);

我的猜測是因為程式碼試圖將所有參數保存在寄存器中,因此 CPU 可以更快地處理它們,如果它必須跟踪額外的 2 個變數,CPU 可能沒有足夠的寄存器。

換句話說,select就是公開一個實現細節,以便它可以更快。

引用自:https://unix.stackexchange.com/questions/7742