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

Я не могу найти много документации, чтобы сказать, должно ли это произойти или нет:

  1. Какой-то поток открывает сокет TCP (или другого потока)
  2. Поток 1 запускает блокировку recv()
  3. Поток 2 вызывает shutdown() в сокете с помощью SHUT_RDWR (или, я думаю, SHUT_RD)
  4. Поток 1 теперь «пробуждается» от своего блокирующего вызова и возвращает ноль, как если бы другая сторона закрыла свой сокет.

Такое поведение проявляется в современных системах Linux и FreeBSD. Я не тестировал его с другими.

Комментарий на странице справки Microsoft MSDN здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740481%28v=vs.85%29.aspx предполагает, что такое поведение является "ответственным" в Windows; в нем также говорится, что это «в настоящее время не так», но это может быть устаревшим.

Это поведение указано где-нибудь? Могу ли я на это положиться?


person MarkR    schedule 07.06.2012    source источник


Ответы (1)


Я не думаю, что вы можете полагаться на это. shutdown() инициализирует отключение сокета, но детали зависят от конкретных обстоятельств. Некоторые протоколы действительно могут немедленно закрыть соединение и сокет, что разбудит процессы, спящие на этом сокете. В других случаях выключение просто запускает конечный автомат протокола, но потребуется некоторое время, прежде чем он дойдет до точки, когда имеет смысл разбудить кого-либо. Например, установленное TCP-соединение должно пройти через несколько состояний, пока не достигнет состояния ЗАКРЫТО. В конце концов вы проснетесь, но вы не можете полагаться на то, что это произойдет сразу.

person ArtemB    schedule 26.06.2013