Яка мета першого аргументу для вибору системного виклику?


25

З man select

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

nfds - це дескриптор файлів з найбільшим числом у будь-якому з трьох наборів плюс 1.

Яка мета nfds, коли ми вже є readfds, writefdsі exceptfdsз якої можна визначити дескриптори файлів?


Я збирався запитати про SO, але це тут більш централізовано, і C API-дзвінки вважаються актуальними .
phunehehe

Відповіді:


25

У "Розширеному програмуванні в середовищі UNIX" У. Річард Стівенс каже, що це оптимізація продуктивності:

Вказавши найвищий дескриптор, який нас цікавить, ядро ​​може уникнути перегляду сотні невикористаних бітів у трьох наборах дескрипторів, шукаючи біти, які увімкнено.

(1-е видання, стор. 399)

Якщо ви виконуєте будь-який тип програмування UNIX систем, книга APUE настійно рекомендується.


ОНОВЛЕННЯ

fd_set, Як правило , в змозі відслідковувати до 1024 дескрипторів файлів.

Найефективнішим способом відстеження, для якого fdsвстановлено, 0а для якого встановлено, був 1би біт, тому кожен fd_setскладався з 1024 біт.

У 32-розрядної системі довгий int (або "слово") становить 32 біти, тобто кожен fd_setозначає
1024/32 = 32 слова.

Якщо nfdsце щось невелике, наприклад 8 або 16, що було б у багатьох програмах, йому потрібно лише заглянути всередину 1-го слова, що явно повинно бути швидшим, ніж заглянути все 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);

Думаю, це тому, що код намагається зберегти всі аргументи в регістрах , щоб процесор міг працювати над ними швидше, і якби йому довелося відслідковувати додаткові 2 змінні, процесор може не мати достатньої кількості регістрів.

Іншими словами, selectрозкрийте деталі реалізації, щоб воно було швидше.


2
Це, або більш пізні The Linux Programming Interface
Крісом

APUE також нещодавно оновлено. Друге видання: amazon.com/gp/aw/d.html/ref=aw_d_detail?pd=1&a=0201433079
Mikel

@chris Я перевірю інтерфейс програмування Linux. Спасибі.
Мікель

Дякую за інформацію, я перевіряю книги, коли захоплю деякий час.
phunehehe

APUE 2nd Ed: 27 червня 2005 (охоплює linux-2.4.22) TLPI: жовтень 2010 (охоплює linux-2.6.35)
chris

6

Я точно не знаю, оскільки я не один з дизайнерів select (), але я б сказав, що це оптимізація продуктивності. Функція виклику знає, скільки дескрипторів файлів він розмістив у програмах для читання, запису, за винятком FD, так чому ядро ​​повинно це з'ясувати?

Пам'ятайте, що на початку 80-х, коли select () було представлено, у них не було багатогігагерців, мультипроцесорів, з якими можна було б працювати. 25 МГц VAX був досить швидким. Крім того, ви хотіли, щоб select () працював швидко, якщо це міг: якщо якийсь ввід / вивід чекав процесу, навіщо змусити процес чекати?


На ваш аргумент я б сказав, що нам потрібно nreadfds, nwritefdsа nexceptfdsне лише один nfds.
phunehehe

Можливо, це так, що nfdsможе зайти в реєстр для швидшого доступу. Якби довелося відслідковувати три числа разом з усіма іншими аргументами, можливо, ЦП не матиме достатньої кількості регістрів. Звичайно, ядро ​​могло б створити своє власне nfdsна основі ваших гіпотетичних 3 змінних. Тож я здогадуюсь, що це розкриття деталей реалізації для підвищення ефективності.
Мікель

@Mikel, phunehehe: Окремі nfdsаргументи принесуть дуже мало користі. У більшості випадків цей процес відкривав дуже мало процесів щодо FD_SETSIZE. Типовий випадок може бути (4,4,2) з 1024; зробити перевірку ядра (4,4,4) - це велика перемога (1024,1024,1024), але оптимізація до (4,4,2) була б майже марною.
Жил "ТАК - перестань бути злим"

@Gilles: посилення буде чистішим API. (Як це є, або програмісту доводиться робити додаткову роботу, щоб обчислити nfds, або лінуватися і дзвонити select(FD_SETSIZE, ...), що буде повільніше.)
Mikel

OTOH, відстеження лише однієї максимальної змінної також може бути простішим для програміста.
Мікель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.