Безопасно ли выполнять блокирующие вызовы write () для одного и того же сокета TCP из нескольких потоков? - PullRequest
10 голосов
/ 22 сентября 2009

Допустим, у меня есть два потока, T1 и T2.

Поток T1 выполняет блокирующий вызов write () на TCP-сокете S для отправки большого буфера байтов B1. Буфер байтов B1 настолько велик, что (a) блоки вызова записи и (b) TCP должны использовать несколько сегментов для отправки буфера.

Поток T2 также выполняет блокирующий вызов write () в том же TCP-сокете S для отправки другого большого буфера байтов B2.

Мои вопросы таковы:

Гарантирует ли реализация TCP в UNIX, что все байты B1 будут отправлены раньше всех байтов B2 (или наоборот)?

Или возможно, что TCP перемежает содержимое B1 и B2 (например, TCP отправляет сегмент с данными B1, затем сегмент с данными B2, а затем снова сегмент с данными B1).

PS - Я знаю, что это плохая идея. Я пытаюсь определить, верен ли какой-то код, который я не написал.

1 Ответ

11 голосов
/ 22 сентября 2009

Пытается

TL; DR: с целью написания и отладки кода можно предположить атомарность, если только ваша цель не система жизнеобеспечения.


Всегда будет плохо, если send(2) (аналогично write(2)) на сокете tcp не является атомарным. Нет веской причины для реализации неатомарной записи. Все версии Unix и Windows пытаются сохранить запись на атомарном уровне, но, очевидно, очень немногие предоставляют гарантию.

Linux, как известно, "обычно" 1. понимает это правильно, но в нем есть ошибка, даже в недавних ядрах. Он пытается заблокировать сокет, но при определенных обстоятельствах выделение памяти может быть неудачным, и запись будет разделена. Подробности смотрите в этой записи блога IBM на sendmsg . [ссылка исправлена.]

Согласно этим тестам, только AIX и Solaris полностью прошли стресс-тест потока. Неизвестно, были ли даже в этих системах случаи сбоев, которые просто не были обнаружены.


1. TL; DR: почти всегда, т.е. всегда, за исключением случаев наличия определенной ошибки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...