Select

為什麼選擇系統呼叫需要加1?

  • May 5, 2022

來自man select

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

nfds 應設置為三個集合中任何一個中編號最高的文件描述符,加 1。

我很好奇:

  1. 為什麼plus 1需要,而不是最高編號的文件描述符本身?
  2. 為什麼在使用者輸入中請求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 開始,如果nfdsn ,則將考慮從 0 到n–1 的文件描述符。

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