Параллельные вызовы к send/recv на том же допустимом сокете?

  1. Можем мы звонить отправить от одного потока и recv от другого на том же сокете?
  2. Мы можем звонить, несколько отправляют parallely от различных потоков на том же сокете?

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

Любые указатели в направлении будут полезны.

119
задан Jay 30 December 2009 в 18:03
поделиться

3 ответа

POSIX определяет send/recv как атомарную операцию, поэтому, если вы говорите о POSIX send/recv, то да, вы можете вызывать их одновременно из нескольких потоков, и все будет работать.

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

Если вы используете сокеты SOCK_STREAM, попытка делать вещи параллельно менее полезна, так как send/recv может послать или получить только часть сообщения, что означает, что вещи могут разбиться.

Блокирование send/recv в сокетах SOCK_STREAM блокирует только до тех пор, пока они не отправят или не перешлют не менее 1 байта, поэтому разница между блокировкой и неблокировкой не является полезной.

86
ответ дан 24 November 2019 в 01:52
поделиться

Я не понимаю, как параллельный прием может что-то сделать. Если у вас сообщение длиной 3 байта, то 1 поток может получить 1 2 байта, а другой последний байт, но вы не сможете сказать, какой из них. Если только ваши сообщения не имеют длины всего лишь один байт, вы не сможете надежно заставить что-либо работать при получении нескольких потоков.

Multiple sends may might work, если вы отправили все сообщение за один звонок, но я не уверен. Возможно, что одно сообщение может перезаписать другое. Конечно, это не принесло бы никакой пользы.

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

.
4
ответ дан 24 November 2019 в 01:52
поделиться

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

Однако, если порядок отправки/приема семантически значим, то вы сами (соответственно ваш код) должны обеспечить правильную последовательность между операциями в разных потоках, как это всегда бывает в случае с потоками.

17
ответ дан 24 November 2019 в 01:52
поделиться
Другие вопросы по тегам:

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