Должны ли сокеты быть неблокирующими для работы с select в Python? - PullRequest
5 голосов
/ 08 марта 2011
  1. Должны ли сокеты быть неблокирующими при использовании с select.select в Python?
  2. Какая разница, если они есть или нет?

Иногда я обнаруживаю, что вызов send в сокете, который возвращает sendable, блокируется. Кроме того, я обнаружил, что блокировка , блокирующая сокеты , обычно отправляет весь указанный буфер (128 КиБ). В неблокирующем режиме отправка примет гораздо меньше байтов (20-40 КиБ по сравнению с примером, приведенным ранее) и вернется быстрее. Я использую Python 3.1 на Lucid .

1 Ответ

5 голосов
/ 08 марта 2011

К сожалению, ответ может зависеть от ОС.Я отвечаю только в отношении Linux.

Я не знаю различий в отношении блокирующих / неблокирующих сокетов в select, но в linux на странице справки по системному вызову select есть сообщение BUGSsection:

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

Я сомневаюсь в абстракции Python выше, которая могла бы "скрыть" эту проблему без побочных эффектов.

Что касаетсяблокирующая запись отправляет больше данных, что ожидается.send будет блокироваться, пока не будет достаточно буферного пространства для передачи всего вашего запроса, если сокет блокируется.Если сокет не является блокирующим, он отправляет только столько, сколько может поместиться в буфере отправки сокета.

...