Управляемый событиями ввод-вывод и блокировка против неблокирования - PullRequest
3 голосов
/ 27 апреля 2011

Может ли кто-нибудь объяснить мне, как управляемые событиями системные вызовы ввода-вывода, такие как select, poll и epoll, связаны с блокирующим или неблокирующим IO?

Я не понимаю, как это связано - если вообщеэти понятия

Ответы [ 3 ]

6 голосов
/ 27 апреля 2011

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

  1. В старых версиях Linux определенно есть ошибки в ядре, где read может блокировать даже после того, как select указывает, что сокет доступен для чтения (это произошло с сокетами UDP и пакетами с неверными контрольными суммами). Текущие версии Linux могут по-прежнему иметь такие ошибки; Я не уверен.

  2. Если есть какая-либо возможность, что другие процессы имеют доступ к вашим файловым дескрипторам и будут читать / записывать их, или если ваша программа многопоточная и другие потоки могут это делать, то между * существует условие гонки select определение того, что файловый дескриптор доступен для чтения / записи и ваша программа выполняет IO, что может привести к блокировке.

  3. Вы почти наверняка хотите сделать неблокирующий сокет перед вызовом connect; в противном случае вы будете блокировать, пока не будет установлено соединение. Используйте select для записи, чтобы определить, когда оно успешно подключено, и select для ошибок, чтобы определить, не удалось ли установить соединение.

5 голосов
/ 27 апреля 2011

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

epoll предоставляется только в Linux для той же цели, но это огромное улучшение по сравнению с select с точки зрения эффективности и интерфейса программирования. Другие Unix'ы тоже имеют свои специализированные вызовы.

Тем не менее, управляемые событиями системные вызовы ввода-вывода не требуют ни блокирующих, ни неблокирующих дескрипторов. Блокировка - это поведение, которое влияет на системные вызовы, такие как read, write, accept и connect. select и epoll_wait имеют таймауты блокировки, но это не относится к дескрипторам.

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

Неблокирующая, управляемая событиями IO может сделать серверные приложения значительно более эффективными, потому что потоки не нужны для каждого дескриптора (соединения). Сравните производительность веб-сервера Apache с Nginx или Lighttpd, и вы увидите преимущество.

0 голосов
/ 27 апреля 2011

select и аналогичные функции (вы упомянули несколько) обычно используются для реализации цикла событий в системе, управляемой событиями.

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

Когда дескриптор файла становится доступным, вы можете быть уверены, что данные доступны, и операция read () не заблокируется.

Это один из способов обработки данных из нескольких источников одновременно без использования нескольких потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...