select изменяет свои аргументы. Вы действительно должны каждый раз заново инициализировать его.
Если вас беспокоят издержки, стоимость обработки полного FD_SET в ядре несколько более значительна, чем стоимость FD_ZERO. Вы бы хотели передать только ваш максимальный fd, а не FD_SETSZIZE, чтобы минимизировать обработку ядра. В вашем примере:
switch (select((sd + 1),&set,NULL,NULL,&timeout))
Для более сложного случая с несколькими fds вы обычно поддерживаете переменную max:
FD_SET(sd,&set);
if (sd > max) max = sd;
... repeat many times...
switch (select((max + 1),&set,NULL,NULL,&timeout))
Если у вас будет большое количество файловых дескрипторов, и вы обеспокоены накладными расходами, связанными с их отбрасыванием, вам следует взглянуть на некоторые альтернативы select (). Вы не упоминаете используемую ОС, но для Unix-подобных ОС их несколько:
- для Linux, epoll ()
- для FreeBSD / NetBSD / OpenBSD / MacOS X, kqueue ()
- для Solaris, / dev / poll
API-интерфейсы разные, но все они по сути являются интерфейсом ядра с сохранением состояния для поддержки набора активных описаний файлов. Как только fd будет добавлен в набор, вы будете уведомлены о событиях на этом fd без необходимости постоянно передавать его снова.