Які гарантії для одночасного запису в названу трубу?


32

Наприклад, я створив названу трубу на зразок наступного:

mknod myPipe p

І я читаю з нього з якогось процесу (наприклад, якогось сервера). Наприклад, я використовував хвіст:

tail -f myPipe

Якщо декілька клієнтських процесів записують у нього деякі повідомлення (наприклад echo "msg" >> myPipe, чи є певний шанс, що повідомлення будуть переплетені, як це:

 <beginning of message1><message2><ending of message1>

Або процес запису до названої труби є атомним?

Відповіді:


29

Це залежить від того, скільки пише кожен процес (якщо припустити, що ваша ОС відповідає POSIX у цьому плані). Від write():

Записи запису в трубу або FIFO обробляються так само, як і у звичайному файлі, з такими винятками:
[...]

  • Запити запису на {байтів {PIPE_BUF} або менше не повинні переплітатися з даними інших процесів, що записують у ту саму трубку. Записи, що перевищують {BIPE_BUF} байтів, можуть мати переплетені дані на довільних кордонах з записами іншими процесами, незалежно від того, встановлено прапор O_NONBLOCK прапорів статусу файлу чи ні.

Також у розділі " Обгрунтування " стосовно труб та FIFO:

  • Атомний / неатомний : запис є атомним, якщо вся сума, записана за одну операцію, не переплітається з даними жодного іншого процесу. Це корисно, коли є кілька авторів, які надсилають дані на один зчитувач. Програми повинні знати, наскільки велике запит на запис можна очікувати виконання атомно. Цей максимум називається {PIPE_BUF}. Цей обсяг POSIX.1-2008 не говорить про те, чи запити запису на більше байтів {PIPE_BUF} є атомними, але вимагає, щоб записи в розмірі {PIPE_BUF} або менше байтів були атомними.

Значення, якщо PIPE_BUFвизначається кожною реалізацією, але мінімум - 512 байт (див. limits.h). В Linux це 4096 байт (див. pipe(7)).


5
PIPE_BUF, до речі, гарантовано принаймні 512. Зверніть увагу, що ви також повинні гарантувати, що ваш процес фактично записує кожен рядок до нього в одному дзвінку на запис. Увімкнення буферизації ліній ( setvbuf(stdout, NULL, _IOLBF,512)) зробить це без необхідності використання функцій низького рівня.
Випадково832

Ось таблиця спостережуваних PIPE_BUFзначень у загальних системах Unix: ar.to/notes/posix#pipe-buf
Arto Bendiken

Я не розумію, як розетки можуть бути мультиплексовані ... але названі труби не можуть ?? все на unix - це просто файл, правда? lulz
Олександр Міллс

@AlexanderMills: Я не розумію ваш коментар
Мат

1
Чи не @AlexanderMills: Ні, це мінімальне значення
Mat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.