Select
為什麼選擇系統呼叫需要加1?
來自
man select
:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
nfds 應設置為三個集合中任何一個中編號最高的文件描述符,加 1。
我很好奇:
- 為什麼
plus 1
需要,而不是最高編號的文件描述符本身?- 為什麼在使用者輸入中請求
plus 1
操作,而不是在系統內部處理呢?從
sys_generic.c
,它似乎相關__NFDBITS
,但我無法更進一步。static int max_select_fd(unsigned long n, fd_set_bits *fds) 339{ 340 unsigned long *open_fds; 341 unsigned long set; 342 int max; 343 struct fdtable *fdt; 344 345 /* handle last in-complete long-word first */ 346 set = ~(~0UL << (n & (__NFDBITS-1))); 347 n /= __NFDBITS; 348 fdt = files_fdtable(current->files); 349 open_fds = fdt->open_fds->fds_bits+n; 350 max = 0; 351 if (set) { 352 set &= BITS(fds, n); 353 if (set) { 354 if (!(set & ~*open_fds)) 355 goto get_max; 356 return -EBADF; 357 } 358 } 359 while (n) { 360 open_fds--; 361 n--; 362 set = BITS(fds, n);
類似的主題但不一樣:
to的
nfds
參數select
指定如下:nfds參數指定要測試的描述符範圍。應在每組中檢查第一個nfds描述符;也就是說,應檢查描述符集中從零到nfds -1 的描述符。
換句話說,
nfds
給出文件描述符的計數,它本身不是文件描述符。它的最小意義值是 1,而不是 0(從技術上講,nfds
可以是 0;select
在這種情況下什麼都不做,也可能根本不被呼叫,除非你對它的副作用之一感興趣,例如等待暫停)。該
nfds
值指定呼叫者想要查看多少個文件描述符;由於文件描述符從 0 開始,如果nfds
是n ,則將考慮從 0 到n–1 的文件描述符。