API сокетов C является потокобезопасным?

Я использую как API-интерфейсы Linux, так и Win32. В моей программе несколько потоков совместно используют дескриптор сокета. В частности, несколько потоков обращаются к send с общим дескриптором сокета (т.е. С тем же портом). В этом случае мне нужно установить блокировку для безопасности потоков? Я не смог найти ответ. Я могу сделать тест, но хочу услышать ваши впечатления.

РЕДАКТИРОВАТЬ. Я знаю, что такая отправка данных через сокет вовсе не является атомарной. Определенно нам нужно использовать мьютекс для обеспечения безопасности потоков. Однако мне было интересно, может ли системный API иметь собственный внутренний замок. Если это так, мы можем опустить собственный замок.

Этот вопрос может быть применим и к функции fprintf. Мне интересно, что такие системные API будут иметь свои собственные блокировки. По моему опыту, вызов fprintf из нескольких потоков не убивал мою программу, хотя в файле или stdout были расы (т.е. Непоследовательные или непредсказуемые выходы, но программа не была разбита), что подразумевало, что fprintf имел блокировку для защиты их внутренней структуры данных.

Ответы

Ответ 1

Сокеты не являются частью стандарта С++, поэтому это зависит от реализации. Как правило, они не являются потокобезопасными, поскольку send не является атомной операцией. Подробнее см. эту дискуссию.

EDIT: ОС может иметь или не иметь внутренний замок для защиты внутренних структур. Это зависит от реализации. Поэтому вы не должны рассчитывать на это.

Ответ 2

Я нахожу, что дескриптор дескриптора файла close close() чрезвычайно опасен в параллельной среде.

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

Ответ 3

Отправка данных через сокет не является атомной транзакцией - любая неатомная транзакция потребует блокировки/синхронизации. Это не зависит от платформы.

Ответ 4

Нет, переменная, созданная с помощью accept, не должна быть мьютексом. Любые данные, используемые потоками, должны быть, по крайней мере, семафорами.

sem_t* sem_data;