Выберите функцию в программировании сокета - PullRequest
15 голосов
/ 13 ноября 2010

Может кто-нибудь сказать мне об использовании и применении функции select в программировании сокетов в c?

Ответы [ 6 ]

46 голосов
/ 13 ноября 2010

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

Допустим, вы хотите написать программу, которая реагирует на события, поступающие из нескольких источников, например сеть (через сокеты), пользовательский ввод (через stdin), другие программы (через каналы) или любой другой источник событий, который может быть представлен fd. Вы можете запустить отдельные потоки для обработки каждого источника событий, но вам придется управлять потоками и решать проблемы параллелизма. Другой вариант - использовать механизм, в котором вы можете объединить все fd в единый объект fdset, а затем просто вызвать функцию для ожидания на fdset. Эта функция будет возвращаться всякий раз, когда происходит событие на любом из fd. Вы можете проверить, на каком fd событии произошло, прочитать это fd, обработать событие и ответить на него. После того, как вы это сделаете, вы вернетесь назад и будете сидеть в этой функции ожидания - пока не прибудет другое событие на каком-то fd.

Механизм

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

9 голосов
/ 13 ноября 2010

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

Чтение: Когда любой из файловых дескрипторов в этой категории будет готов к чтению, select вернет их вам.

Запись: Когда любой из файловых дескрипторов в этой категории будет готов к записи, select вернет их вам.

Исключительно: Когда у любого из файловых дескрипторов в этой категории есть исключительный регистр, то естьони нечисто закрываются, разрывается соединение или возникает какая-то другая ошибка - select возвращает их вам.

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

Чтобы получить более конкретный ответ, вам, вероятно, придется упомянуть, чтоязык, на котором вы программируете. Я попытался дать как можно более общий ответ на концептуальном уровне.

4 голосов
/ 13 ноября 2010

select () - это нетехнологичный способ опроса сокетов на предмет новых данных для чтения или открытого окна TCP для записи.Если нет веских причин не делать этого, вам, вероятно, лучше использовать poll () или epoll_wait (), если у вашей платформы это есть, для лучшей производительности.

2 голосов
/ 13 ноября 2010

Было бы неплохо подробнее, но я думаю, что вы имеете в виду метод Selector.select () Java NIO.

Простой ответ на ваш вопрос заключается в том, что select () (в этом контексте) будет ожидать, пока канал (то есть одно из сетевых подключений, управляемых этим объектом Selector) будет иметь данные, доступные для чтения.

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

Вот отличный маленький учебник, который должен прояснить ситуацию:

http://rox -xmlrpc.sourceforge.net / niotut /

0 голосов
/ 25 февраля 2016

Мне нравится описание на gnu.org:

Иногда программе необходимо принимать входные данные на нескольких входных каналах при поступлении входных данных.Например, некоторые рабочие станции могут иметь устройства, такие как оцифровывающий планшет, блок функциональных кнопок или блок набора номера, которые подключены через обычные асинхронные последовательные интерфейсы;Хороший стиль пользовательского интерфейса требует немедленной реакции на ввод на любом устройстве.[...]

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

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

0 голосов
/ 13 ноября 2010

Согласно документации для man-страниц Linux и MSDN для Windows,

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

Для простого объяснения: часто это требуется для приложениясделать несколько вещей одновременно.Например, вы можете получить доступ к нескольким сайтам в веб-браузере, веб-сервер может захотеть одновременно обслуживать несколько клиентов.Нужен механизм для отслеживания каждого сокета, чтобы приложение не занималось ожиданием завершения одного сеанса связи.

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

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