Неблокирование сокета с опросом

Несколько дней назад я должен был исследовать проблему, где мое приложение показывало аномально высокое использование ЦП, когда это было (по-видимому), в состоянии ожидания. Я разыскал проблему к циклу, который был предназначен для блокирования на a recvfrom звоните, в то время как сокет был установлен на O_NONBLOCK- луг, приводящий к спин-блокировке. Было два способа решить проблему: установите сокет на блокирование или опросите относительно доступных данных по использованию сокета poll или select. Я выбрал первого, поскольку это было более просто. Но я задаюсь вопросом, почему любой создал бы не блокирующийся сокет и затем опросил бы на нем отдельно. Разве блокирующийся сокет не делает того же? Каковы случаи использования, где можно было бы использовать не блокирующийся сокет и комбинацию опроса? Там какие-либо преимущества к нему в общих случаях?

11
задан 341008 29 July 2010 в 08:51
поделиться

2 ответа

Использование poll() или select() с неблокирующим дескриптором файла дает вам два преимущества:

  • Вы можете установить таймаут для блокировки;
  • Вы можете ждать, пока любой из множества дескрипторов файла станет пригодным для использования.

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

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

8
ответ дан 3 December 2019 в 09:40
поделиться

что приводит к блокировке вращения.

Такое состояние обычно называется тугой петлей.

Было два способа решения проблемы: перевести сокет в режим блокировки или опросить доступные данные на сокете с помощью poll или select. Я выбрал первый вариант, так как он был проще.

Вы уверены, что другие части кода уже не используют poll() (или select()) и ожидают, что сокет будет находиться в неблокирующем режиме?

В противном случае, да, переход в блокирующий режим - самое простое решение.

Лучшим обратно совместимым решением было бы перед вызовом recvfrom() использовать poll() для ожидания, пока сокет станет доступным для чтения. Этот способ гарантирует, что другие части кода будут работать точно так же, как и раньше.

Но мне интересно, зачем кому-то создавать неблокирующий сокет и затем отдельно опрашивать его. Разве блокирующий сокет не делает то же самое?

Для случая recvfrom() мне не известно никакой существенной разницы.

В каких случаях можно использовать неблокирующий сокет и комбинацию опроса? Есть ли какие-либо преимущества в общем случае?

Это может быть простая ошибка кодирования. Или кто-то мог подумать, что recv'ing в узком цикле как-то увеличит производительность.

1
ответ дан 3 December 2019 в 09:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: