нехватка файловых дескрипторов и блокировка файловых дескрипторов

#linux

#linux

Вопрос:

В книге «Интерфейс программирования Linux» (стр.1367)

Соображения о нехватке также могут применяться при использовании ввода-вывода, управляемого сигналом, поскольку в нем также представлен механизм уведомления, запускаемый по границе. В отличие от этого, соображения нехватки не обязательно применимы в приложениях, использующих механизм уведомлений, запускаемый по уровню. Это потому, что мы можем использовать блокирующие файловые дескрипторы с уведомлением, запускаемым по уровню, и использовать цикл, который непрерывно проверяет дескрипторы на готовность, а затем выполняет некоторый ввод-вывод с готовыми дескрипторами, прежде чем еще раз проверить наличие готовых файловых дескрипторов.

Я не понимаю, что означает эта «блокирующая» часть. Я думаю, что не имеет значения, используем ли мы блокирующий ввод-вывод или неблокирующий. (Автор также говорит в начале главы, что неблокирующий ввод-вывод обычно используется независимо от уведомления, запускаемого по уровню или по границе)

Комментарии:

1. Я думаю, это означает «может использовать блокирующие файловые дескрипторы с уведомлением, инициируемым уровнем», против «не может надежно использовать блокирующие файловые дескрипторы с уведомлением, инициируемым краем». В любом случае, я не думаю, что блокирование файловых дескрипторов всегда гарантированно не блокируется уведомлением, инициируемым уровнем. Поэтому используйте неблокирующие сокеты, если вы не хотите блокировать когда-либо.

Ответ №1:

SO, IO eh? Что ж, IO «обрабатывает вещи», поэтому мы можем использовать человеческую метафору. Представьте, что вы являетесь процессом в системе, выполняющим работу для вашего босса.

Тогда блокировка ввода-вывода похожа на поход к стоматологу или личную встречу с клиентом. В обоих этих сценариях, когда вы отправляетесь проводить это мероприятие, вы находитесь вдали от своего рабочего места и поэтому совершенно неспособны делать что-либо еще, пока не вернетесь за свой рабочий стол. Скорее всего, вы потеряете некоторое время в комнате ожидания или на пустой болтовне на собрании / в ожидании, когда появятся люди.

Блокировка ввода-вывода выглядит следующим образом — блокировка ввода-вывода «жертвует» (я говорю это, потому что вы фактически теряете поток) потоком для рассматриваемой задачи. Вы не можете использовать его для каких-либо других целей, пока он заблокирован — он ожидает выполнения этого ввода-вывода.

Неблокирующий ввод-вывод, напротив, подобен разговору по телефону. Когда вы разговариваете по телефону, вы можете использовать этот ввод-вывод во время написания ответа на Stack Overflow! Такой ввод-вывод называется асинхронным — в том смысле, что вы принимаете запрос ввода-вывода и начинаете его обработку, но можете обрабатывать другие запросы во время их завершения.

Итак, мой любимый ресурс для такого рода вещей — это страница «Проблема с c10k» здесь. Я бы сказал, что вы правы — в 99% случаев вы собираетесь использовать неблокирующий ввод-вывод (фактически, ваша ОС постоянно выполняет неблокирующий ввод-вывод для вас), в основном потому, что использование целого потока для каждой входящей задачи ввода-вывода невероятно неэффективно, даже в Linux, где потоки и процессы — это одно и то же (задачи) и они довольно легкие.

Разница между типами уведомлений, запускаемыми по краю, и типами уведомлений, запускаемых по уровню, вероятно, больше применима к неблокирующим соединениям, поскольку в любом случае это было бы неуместно для случая блокировки. Насколько я понимаю, уведомление, инициируемое edge, помечает дескриптор как готовый только при наличии новых данных с момента последнего запроса об обновлении статуса, тогда как при срабатывании level дескриптор помечается как готовый к обработке при наличии доступных данных. Это означает, что интерфейсы с пограничным запуском считаются немного более сложными, поскольку вам приходится обрабатывать входящие данные, когда вы их видите, поскольку вы больше не будете получать уведомления. Теоретически это должно быть более эффективным (меньше уведомлений).

Итак, tl; dr — edge vs level ready — это несколько иные соображения по сравнению с блокирующими и неблокирующими конструкциями, а именно, существует несколько способов выполнения неблокирующего ввода-вывода и действительно только один для выполнения блокирующего ввода-вывода.