В чем разница между источниками отправки GCD и select()?

Я пишу код, который заменяет некоторые существующие:

while(runEventLoop){
  if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){
    // check file descriptors for activity and dispatch events based on same 
  }
} 

код чтения сокета. Я хотел бы изменить это, чтобы использовать очередь GCD, чтобы я мог помещать события в очередь с помощью dispatch_async вместо сохранения массива «должен быть вызван на следующей итерации». Я также уже использую очередь GCD для /contain/ этого конкретного действия, поэтому хочу перевести его в более естественную форму отправки GCD. (не цикл while(), монополизирующий последовательную очередь)

Однако, когда я попытался преобразовать это в форму, которая полагалась на источники отправки, запускаемые обработчиками событий, привязанными к DISPATCH_SOURCE_TYPE_READ и DISPATCH_SOURCE_TYPE_WRITE в дескрипторах сокетов, код библиотеки, который зависел от этого планирования, перестал работать. Мое первое предположение состоит в том, что я неправильно понимаю использование DISPATCH_SOURCE_TYPE_READ и DISPATCH_SOURCE_TYPE_WRITE — я предполагал, что они будут давать примерно то же поведение, что и вызов select() с этими дескрипторами сокетов.

Я неправильно понимаю источники отправки GCD? Или, что касается рефакторинга, я использую его в ситуации, когда он не подходит лучше всего?


person Chris Zelenak    schedule 21.10.2010    source источник
comment
Вы должны показать свой код - что вы пробовали. Тем временем у Майка Эша есть пример кода для проверки — mikeash.com/svn/GCDWeb. /GCDWeb.m — веб-сервер GCD.   -  person zrzka    schedule 26.02.2011


Ответы (1)


Краткий ответ на ваш вопрос: нет. Нет никаких различий, оба источника отправки GCD и select() делают одно и то же: они уведомляют пользователя о том, что произошло определенное событие ядра или что определенное условие выполняется.

Обратите внимание, что на устройствах Mac или iOS вы не должны использовать select(), а лучше использовать более продвинутые kqueue() и kevent() (или kevent64()).

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

Может быть более простым решением может быть сохранение исходного кода, просто добавление кода GCD в ту часть, которая реагирует на события. Здесь вы отправляете события в разные очереди в зависимости от конкретного типа события.

person Massimo Cafaro    schedule 04.03.2011
comment
Я согласен, одно отличие состоит в том, что с помощью GCD вы можете разбить свой код на отдельные конечные автоматы с независимыми очередями отправки, связанными с каждым источником. Я не уверен, но я предполагаю, что внутренне GCD может использовать что-то похожее для выбора самого себя. - person user210504; 04.03.2011
comment
Можете ли вы уточнить, почему kqueue() лучше, чем select() на iOS? Из моего краткого исследования, похоже, что kqueue() предпочтительнее, когда у вас есть много событий для мониторинга, но есть ли основания полагать, что это лучше, чем select() на fdset с одним fd? В этом случае кажется, что семантика почти идентична, поэтому не уверен, почему производительность будет другой? - person user1055568; 02.10.2013
comment
Спектакли на самом деле разные: просто попробуйте сами. Вы должны увидеть, что даже для одного файлового дескриптора с интенсивной активностью kqueue() работает лучше. Вероятно, Apple не слишком настаивала на улучшении старой реализации select(). Новый системный вызов queue() намного мощнее и работает лучше. Единственная причина, по которой я вижу использование select(), заключается в том, что у вас есть устаревший код, который вы не хотите обновлять. - person Massimo Cafaro; 03.10.2013
comment
Спасибо! Я попробую. Я не сделал этого сразу, потому что подумал, что может потребоваться некоторая работа по настройке надлежащего тестового примера и измерения. У меня есть устаревший код и другие платформы для поддержки, но это должно быть легко. На самом деле я надеюсь на лучшую реакцию на параметр тайм-аута, хотя, возможно, это в основном функция вызова приоритета потока. Жаль, что iOS не поддерживает EVFILT_TIMER, похоже, это именно то, что мне нужно. - person user1055568; 04.10.2013