использование select () для мультиплексирования ввода / вывода - PullRequest
0 голосов
/ 08 января 2019

просто несколько вопросов по мультиплексированию ввода / вывода, мой учебник говорит:

Функциональные блоки выбора до тех пор, пока хотя бы один дескриптор в наборе чтения не будет готов к чтению. Дескриптор k готов к чтению тогда и только тогда, когда запрос на чтение 1 байта из этого дескриптора не заблокируется.

В1-я не понимаю, почему чтение одного байта из дескриптора может блокировать? разве стандартные функции ввода-вывода не используют буфер?

Q2 - почему бы просто не разветвить дочерний процесс и позволить ребенку выполнять работу, которая может блокировать?

В3 - если я использую небуферизованный системный вызов read () для чтения большого количества байтов из двух открытых файлов, так что все они блокируются (занимают много времени), так как же select () выполняет демультиплексирование?

1 Ответ

0 голосов
/ 08 января 2019

Вы неправильно понимаете справочную страницу select (2) (см. Также select_tut (2) ). Кстати, вам лучше использовать poll (2) в новом коде, например this ; поскольку select ограничивает (размером fd_set) самый высокий дескриптор файла, который он может использовать (представьте себе проблему C10K ).

Страница man select определяет файловый дескриптор вашего процесса как ready ...

... если возможно выполнить соответствующую операцию ввода / вывода (например, read (2) без блокировки или достаточно небольшая write (2) ).

То есть, если дескриптор файла таков, что вы могли бы успешно прочитать (2) хотя бы один байт из него, это готовый дескриптор файла (для read с). Большую часть времени вы сможете прочитать несколько байтов из него. Файловый дескриптор, из которого вы не можете read, так как попытка read (2) заблокировала бы, не готова, поэтому ее можно назвать заблокированным дескриптором файла.

Существует несколько случаев блокировки файлового дескриптора (то есть не готового). Обычно используется сетевой разъем (7) или pipe (7) (или какой-либо терминал, см. pty (7) и TTY демистифицирован и помните, что дисциплина линии ) больше не имеет ввода. Вот почему poll (или select, epoll (7) и т. Д.) Необходимы для кодирования циклов событий (в частности, в наборах инструментов виджетов для графического интерфейса пользователя, на веб-серверах и т. Д.), Поскольку вы хотите избежать занятости опрос .

Для более подробного объяснения прочитайте хорошую книгу по программированию для Linux, такую ​​как ALP .

Вы также можете прочитать Операционные системы: три простых компонента , чтобы получить больше знаний об ОС.

Имейте в виду, что stdio (3) реализует буферизованный IO (выше read (2) и write (2) ) , Смотрите также fflush (3) и setvbuf (3) .

См. Также proc (5) , чтобы программно запрашивать состояние процессов (большинство из них бездействуют , поскольку заблокированы в операциях ввода-вывода или циклах событий). Или используйте ps (1) , top (1) (оба используют /proc/) в командах.

Наконец, просмотрите исходный код многих бесплатных программ проектов (например, веб-серверы, наборы инструментов для графического интерфейса пользователя и т. Д.). Вы можете найти много примеров циклов событий, используя select или poll.

...