Трубы
Да, неблокирующая емкость обычно составляет 4 КБ, но для максимальной переносимости вам, вероятно, лучше использовать константу PIPE_BUF
.Альтернативой является использование неблокирующего ввода-вывода.
Больше информации, чем вы хотите знать, в man 7 pipe
.
Unix-дейтаграмм-сокетах
Запись с использованием send
семейство функций на сокетах дейтаграмм действительно гарантированно будет атомарным .В случае с Linux они также надежны и сохраняют порядок.(что делает недавнее введение SOCK_SEQPACKET
немного смущающим меня) Много информации об этом в man 7 unix
.
Максимальный размер датаграммы зависит от сокета.Доступ к нему осуществляется с помощью getsockopt/setsockopt
на SO_SNDBUF
.В системах Linux он колеблется между 2048 и wmem_max
, по умолчанию wmem_default
.Например, в моей системе wmem_default = wmem_max = 112640
.(вы можете прочитать их из /proc/sys/net/core
). Наиболее релевантная документация по этому вопросу находится в man 7 socket
вокруг опции SO_SNDBUF
.Я рекомендую вам прочитать его самостоятельно, так как описываемое им поведение удвоения емкости может сначала немного запутать.
Практические различия между потоком и датаграммой
Потоковые сокеты работают только при подключении.Это в основном означает, что они могут общаться только с одним пэром одновременно.Как потоки, они не гарантированно сохраняют «границы сообщений».
Дейтаграммные сокеты отключены.Они могут (теоретически) общаться с несколькими пэрами одновременно.Они сохраняют границы сообщений.
[Я полагаю, что новый SOCK_SEQPACKET
находится между: подключен и сохраняет границы.]
В Linux оба надежны и сохраняют порядок сообщений.Если вы используете их для передачи потоковых данных, они, как правило, работают аналогично.Так что просто используйте тот, который соответствует вашему потоку, и позвольте ядру обрабатывать буферизацию для вас.
Необработанный тест сравнения потоков, дейтаграмм и каналов:
# unix stream 0:05.67
socat UNIX-LISTEN:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-CONNECT:u
# unix datagram 0:05.12
socat UNIX-RECV:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-SENDTO:u
# pipe 0:05.44
socat PIPE:p,rdonly=1 OPEN:/dev/null &
until [[ -p p ]]; do :;done
time socat OPEN:large-file PIPE:p
Ничего статистически значимого здесь.Мое узкое место, вероятно, читает большой файл.