Установка бита дескриптора в select ()

В настоящее время я изучаю select () для мультиплексирования ввода-вывода в сетевом программировании. select принимает следующие аргументы:

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

Описание для типа данных fd_set вызова select () имеет следующий вид:

select использует наборы дескрипторов, обычно массив целых чисел, где каждый бит в каждом целом числе соответствует дескриптору. Например, при использовании 32-битных целых чисел первый элемент массива соответствует дескрипторам с 0 по 31, второй элемент массива соответствует дескрипторам с 32 по 63 и так далее.

если это так, то, как я понимаю, если у вас есть дескрипторы 1,4,5 для набора чтения, тогда значение будет установлено как:

LSB                          MSB   

01001100000000000000000000000000    // descriptor bits set corresponding to 1,4,5

0123456........................31  //descriptor bit positions

Биты 0-31 образуют целочисленное значение, равное 50, которое должно быть первым элементом считываемого набора, т.е. [50] в нотации массива, поскольку тип данных fd_set:

typedef struct fd_set {
  u_int  fd_count;
  SOCKET fd_array[FD_SETSIZE];
} fd_set;  

Но когда я проверил strace -p 2172, где 2172 - это pid другого терминала, в котором я набрал команду ls, результат был следующим:

pselect6(1,[0],NULL,NULL,NULL,{[],8})

зачем читать дескриптор, установленный в массиве pselect6: [0], когда дескриптор fd, связанный со стандартным вводом, равен 0, поэтому целочисленное значение становится 1, то есть [1]? Правильно ли я истолковал описание?

Кроме того, что произойдет, если вы установите для чтения, а также набор исключений, и во время вызова для выбора дескрипторы только в наборе для чтения готовы к операции чтения и возвращаются. Однако позже будут готовы дескрипторы для набора исключений, но, поскольку select уже вернул, то что вернет проверка на FD_ISSET (int fd, fd_set * exceptSet)?

Я новичок в сетевом программировании.


person POOJA GUPTA    schedule 03.02.2018    source источник
comment
Я думаю, что strace отображает набор дескрипторов как массив FD, а не фактические двоичные данные.   -  person Barmar    schedule 03.02.2018
comment
@Barmar: а массив FD должен быть только [1]?   -  person POOJA GUPTA    schedule 03.02.2018
comment
Стандартный ввод - FD 0, поэтому [0] означает, что набор FD содержит 0.   -  person Barmar    schedule 03.02.2018
comment
@Barmar: вы можете увидеть вышеупомянутый вопрос еще раз, пожалуйста, если стандартный FD равен 0, тогда каждое значение в массиве является целым числом, сформированным после установки бита для этого дескриптора. Сформированное целочисленное значение должно быть 1, следовательно, массив равен [1].   -  person POOJA GUPTA    schedule 03.02.2018
comment
@POOJAGUPTA Верно. Но strace не показывает буквальные целочисленные значения, переданные в select; он показывает вам список файловых дескрипторов. Например, если вы вызвали select() со стандартным вводом, выводом и ошибкой (FD 0, 1 и 2), он отобразится как [0,1,2].   -  person    schedule 03.02.2018
comment
@Barmar: Я полностью с вами согласен, но тогда мой вопрос: какой стандарт? Означает ли это, что дескрипторы представлены внутри и по-разному? тогда это очень сбивает с толку.   -  person POOJA GUPTA    schedule 03.02.2018
comment
Нет стандарта, внутреннее представление зависит от реализации.   -  person Barmar    schedule 03.02.2018
comment
@Barmar: Большое спасибо за ваше терпение и ответ :) И что вы можете сказать о втором запросе?   -  person POOJA GUPTA    schedule 03.02.2018
comment
Я не понимаю второго вопроса. Вы должны проверять каждый набор дескрипторов отдельно. Наборы чтения и исключения могут иметь разные дескрипторы, и вам нужно проверить их оба и выполнить необходимую обработку.   -  person Barmar    schedule 03.02.2018
comment
@barmar: мы будем проверять каждый набор дескрипторов отдельно, но что, если выборка вернется только с дескрипторами, готовыми в наборе для чтения, поскольку они были готовы к чтению в то время. Но позже дескриптор в наборе исключений получает исключение, но не в то время, когда был возвращен первый выбор. Итак, пропустим ли мы этот сигнал для набора исключений, если мы не используем select итеративно и используем только один раз?   -  person POOJA GUPTA    schedule 03.02.2018
comment
Если вы хотите получить больше событий позже, вы должны продолжать называть это. Он не может предсказать будущее.   -  person Barmar    schedule 03.02.2018
comment
Если вы используете его только один раз, вы получите только первое событие. Это простая логика.   -  person Barmar    schedule 03.02.2018


Ответы (1)


strace не показывает фактические двоичные значения в fd_set. Он переводит его в список номеров FD, которым он соответствует. Таким образом, если двоичное значение равно 01001100000000000000000000000000, будет отображаться [1,4,5].

Внутренняя реализация fd_set зависит от реализации, и вам не нужно беспокоиться об этом. Вы просто используете макросы в <select.h> для установки, очистки и проверки дескрипторов в наборе.

person Barmar    schedule 03.02.2018