Из справочной страницы на recv
recv () для сокета SOCK_STREAM
возвращает как можно больше доступной информации
так как размер поставляемого буфера может
держать.
Предположим, вы используете TCP, так как он не был указан в вопросе. Предположим, что у вас есть поток A и поток B, которые блокируют функцию recv () для сокета s. Как только s получит некоторые данные, он разблокирует один из потоков, скажем, A, и вернет данные. Возвращенные данные будут иметь произвольный размер, насколько нам известно. Поток A проверяет полученные данные и решает, имеет ли оно полное «сообщение», где сообщение является концепцией прикладного уровня.
Поток A решает, что не имеет полного сообщения, поэтому он снова вызывает recv (). НО в это время B уже блокировал тот же сокет и получил остальную часть «сообщения», предназначенного для потока A. Здесь я использую намеренно свободно.
Теперь поток A и поток B имеют неполное сообщение и, в зависимости от того, как написан код, будут выбрасывать данные как недействительные или вызывать странные и тонкие ошибки.
Я бы хотел сказать, что не знал этого по опыту.
Так что, хотя сам recv () технически безопасен для потоков, плохая идея иметь два потока, вызывающих его одновременно, если вы используете его для TCP.
Насколько я знаю, это абсолютно безопасно, когда вы используете UDP.
Надеюсь, это поможет.