Редагувати: оновлено серпень 2017 року з останніми результатами Windows.
Я збираюся дати вам відповідь із посиланнями на тестовий код та результати, як автор запропонованого Boost.AFIO, який реалізує асинхронну файлову систему та файли i / o C ++ бібліотеку.
По-перше, O_APPEND або еквівалентний FILE_APPEND_DATA для Windows означає, що прирости максимального розміру файлу ("довжина файлу") є атомарними під одночасними записами. Це гарантується POSIX, а Linux, FreeBSD, OS X і Windows всі реалізують це правильно. Samba також реалізує це правильно, NFS перед v5 не має, оскільки у нього відсутня можливість проводного формату для атомного додавання. Отже, якщо ви відкриєте свій файл лише для додавання, одночасне записування не зірветься відносно один одного на будь-якій великій ОС, якщо не задіяний NFS.
Однак одночасно зчитування атомних додатків може бачити розірвані записи залежно від ОС, системи подачі файлів та яких прапорів, з якими ви відкрили файл - приріст максимального розміру файлу є атомним, але видимість запису щодо прочитаних може бути, а може і не може бути атомним. Ось короткий підсумок прапорів, ОС та системи подачі даних:
Ні O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 з NTFS: оновлення atomicity = 1 байт до включення 10.0.10240, з 10.0.14393 принаймні 1 Мбіт, ймовірно, нескінченно (*).
Linux 4.2.6 з ext4: оновлення atomicity = 1 байт
FreeBSD 10.2 з ZFS: оновлення атомності = принаймні 1 Мб, ймовірно, нескінченно (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 з NTFS: оновіть atomicity = до 10.0.10240 і включають до 4096 байт, лише якщо вирівняні сторінки, інакше 512 байт, якщо FILE_FLAG_WRITE_THROUGH відключений, інакше 64 байти. Зауважте, що ця атомність, ймовірно, є особливістю PCIe DMA, а не розробленою. З 10.0.14393 принаймні 1 Мб, ймовірно, нескінченно (*).
Linux 4.2.6 з ext4: оновлення atomicity = принаймні 1 Мбіт, ймовірно, нескінченно (*). Зауважте, що раніше Linux з ext4 точно не перевищували 4096 байт, XFS, звичайно, раніше користувальницьке блокування, але, схоже, нещодавно Linux остаточно виправив це.
FreeBSD 10.2 з ZFS: оновлення атомності = принаймні 1 Мб, ймовірно, нескінченно (*)
Ви можете ознайомитись з необґрунтованими результатами емпіричного тесту на https://github.com/ned14/afio/tree/master/programs/fs-probe . Зауважимо, ми перевіряємо наявність розірваних зсувів лише на кратних 512 байтах, тому я не можу сказати, чи часткове оновлення сектору 512 байт зірветься під час циклу читання-зміни-запису.
Отже, щоб відповісти на запитання ОП, записи O_APPEND не заважатимуть одне одному, але при читанні одночасно з O_APPEND записи, ймовірно, побачать зірвані записи в Linux з ext4, якщо не буде включено O_DIRECT, після чого ваші записи O_APPEND повинні бути розміром сектора кратним.
(*) "Мабуть нескінченна" випливає з цих пунктів у специфікації POSIX:
Усі наступні функції повинні бути атомними відносно один одного в ефектах, зазначених у POSIX.1-2008, коли вони працюють на звичайних файлах або символічних посиланнях ... [багато функцій] ... читати () ... писати ( ) ... Якщо дві нитки викликають кожну з цих функцій, кожен виклик повинен бачити всі зазначені ефекти іншого виклику, або жодну з них. [Джерело]
і
Записи можуть бути серіалізовані стосовно інших читань і записів. Якщо читання () даних файлів може бути доведено (будь-якими способами) після запису () даних, воно повинно відображати це записування (), навіть якщо виклики здійснюються різними процесами. [Джерело]
але навпаки:
Цей том POSIX.1-2008 не визначає поведінку одночасного запису у файл із декількох процесів. Програми повинні використовувати певну форму контролю за одночасністю. [Джерело]
Детальніше про значення цих питань ви можете прочитати у цій відповіді
fsync(2)
дається стільки ж гарантії, скільки єsync(2)
, і не має настільки ж великого впливу на продуктивність.