- Можем ли мы вызвать send из одного потока и recv из другого в том же сокете?
- Можно ли вызывать несколько отправок одновременно из разных потоков в одном сокете?
Я знаю, что хороший дизайн должен избегать этого, но я не понимаю, как эти системные API-интерфейсы будут себя вести. Я не могу найти хорошую документацию для того же самого.
Любые указатели направления будут полезны.
c
networking
sockets
сойка
источник
источник
Ответы:
POSIX определяет send / recv как атомарные операции, поэтому, если вы говорите о POSIX send / recv, тогда да, вы можете вызывать их одновременно из нескольких потоков, и все будет работать.
Это не обязательно означает, что они будут выполняться параллельно - в случае нескольких отправок вторая, скорее всего, будет заблокирована до завершения первой. Вы, вероятно, этого не заметите, поскольку отправка завершается, как только данные помещаются в буфер сокета.
Если вы используете сокеты SOCK_STREAM, попытка делать что-то параллельное вряд ли будет полезно, поскольку send / recv может отправлять или получать только часть сообщения, что означает, что все может разделиться.
Блокирование send / recv на сокетах SOCK_STREAM блокируется только до тех пор, пока они не отправят или не получат хотя бы 1 байт, поэтому разница между блокировкой и неблокировкой бесполезна.
источник
send
возвращается, как только данные помещаются в буфер отправки, и данные отправляются через стек netowrk и выводятся в сеть асинхронно. Таким образом, если у вас есть один поток, отправляющий и один поток, принимающий, вполне возможно (даже вероятно) для отправляющего потока отправить много пакетов до того, как получающий поток получит первый пакет. Это полностью асинхронно и не одновременно.Дескриптор сокета принадлежит процессу, а не конкретному потоку. Следовательно, можно отправлять / получать в / из одного и того же сокета в разных потоках, ОС будет обрабатывать синхронизацию.
Однако, если порядок отправки / получения является семантически значимым, вы сами (соответственно ваш код) должны обеспечить правильную последовательность между операциями в разных потоках - как это всегда бывает с потоками.
источник
Я не понимаю, как параллельное получение может чего-либо достичь. Если у вас есть 3-байтовое сообщение, один поток может получить первые 2 байта, а другой - последний, но у вас не будет возможности определить, какой из них был каким. Если ваши сообщения не имеют длины всего байта, вы не сможете надежно заставить что-либо работать с получением нескольких потоков.
Несколько отправок могут сработать, если вы отправили все сообщение за один вызов, но я не уверен. Возможно, один может перезаписать другой. Конечно, от этого не будет никакого выигрыша в производительности.
Если необходимо отправить несколько потоков, следует реализовать синхронизированную очередь сообщений. Имейте один поток, который выполняет фактическую отправку, который читает сообщения из очереди, а другие потоки ставят в очередь целые сообщения. То же самое будет работать для приема, но поток приема должен знать формат сообщений, чтобы он мог правильно их десериализовать.
источник