Що відбувається, коли ви читаєте файл під час його перезапису?


26

Припустимо, я читаю (cat) файл, поки інший процес переписує його вміст. Чи прогнозований вихід? Що б сталося?


3
Поведінка не визначена, ніколи цього не слід робити.
ромашка

Відповіді:


19

Це залежить від того, що робить письменник.

Якщо автор перезаписує існуючий файл, то читач побачить новий вміст, коли автор переганяє читача, якщо і коли-небудь. Якщо письменник і читач рухаються з різною швидкістю, читач може альтернативно бачити старий і новий вміст.

Якщо автор врізає файл до того, як він почне записувати, читач запустить проти кінця файлу в той момент.

Якщо автор створить новий файл, після чого перемістить новий файл на стару назву, читач продовжує читати зі старого файлу. Якщо відкритий файл переміщено або видалено, процеси, у яких відкритий файл, продовжують читати з цього ж файлу. Якщо файл буде видалений, він фактично залишається на диску (але не може його знову відкрити), поки останній процес не закриє його.

Системи Unix, як правило, не мають обов'язкових блокувань . Якщо програма хоче забезпечити, щоб її компонент запису та компонент для читання не наступали на пальці ніг один одного, розробник повинен використовувати належне блокування. Є кілька винятків, коли файл, відкритий ядром, може бути захищений від запису користувальницькими програмами, наприклад, зображення файлової системи з контуром або виконуваний файл, який виконується в деяких варіантах unix.


Жиль, чи твоє пояснення також застосовується в ftp/ sftpсценаріях? Скажімо, процес починає читати переданий ftpфайл, тоді як інша версія того ж файлу перезаписує його через нову передачу.
iruvar

@ 1_CR Так. У цьому випадку письменник і читач - це ftpd-процеси.
Жил 'SO- перестань бути злим'

який сенс наздогнати тут?
Віктор Чой

@VictorChoy Стандартне значення: починати позаду / після когось іншого і в якийсь момент рухатися попереду.
Жил "ТАК - перестань бути злим"

18

Це класична умова гонки, тому результат за визначенням непередбачуваний.

Серед іншого, це залежить від

  • fopen(3)або open(2)режими запису,
  • як / якщо письменник буферизує свій результат,
  • як читач читає файл,
  • різниця швидкостей між читачем і письменником,
  • різниця в часі між початком читання та письменника.
  • І звичайно, на сучасних багатоядерних машинах речі ще більше ускладнюються іншими чинниками, що знижуються вниз (наприклад, плануванням процесів).

Якщо вам потрібно мати можливість читати файл під час його перезапису, ви можете змусити письменника зробити перехідну копію файлу, змінити його, а потім скопіювати його назад у вихідний файл. Це шлях rsyncробить це, наприклад. Існує ряд способів цього здійснити, але безкоштовний обід немає. У кожного методу є свої недоліки та наслідки.


1
Ця відповідь набагато вичерпніша, ніж моя. Видалення моєї відповіді.
вбивця

0

Попередні респонденти мають більш вичерпні пояснення, ніж це, але ось фокус, який, безумовно, також працює, і він робить саме те, що хоче:

$ tail -f <filename>

Покаже вам кінець файлу під час його написання. Зручно, якщо ви хочете передати STDERR у файл, але все-таки бачити його, наприклад, у іншому вікні терміналу.

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