Unix читает и пишет в один файл атомарно сериализовано? - PullRequest
20 голосов
/ 05 марта 2011

Я хотел бы знать, выполняется ли запись в один файл атомарно, так что запись ("bla bla") и последующая запись ("herp derp") в один и тот же файл никогда не приводят к чередованию, например, "бла герп бла дерп". Предполагая, что эти записи происходят в разных процессах или потоках, что определяет, что будет сделано первым?

Кроме того, всегда ли read () возвращает данные, отражающие файл в состоянии всех предыдущих записей, полностью завершенных (были ли данные фактически записаны на диск или нет)? Например, после записи («herp derp») все последующие чтения всегда будут отражать полные данные, записанные в файл, или последующее чтение иногда будет отражать только «herp», но не «derp» (или иногда не отражать ни одного из данных). совсем)? Что если чтение и запись происходят в разных процессах / потоках?

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

1 Ответ

10 голосов
/ 05 марта 2011

Отдельные write() вызовы обрабатываются отдельно, а не как одна атомарная транзакция записи, и чередование полностью возможно, когда несколько процессов / потоков записывают в один и тот же файл.Порядок фактической записи определяется планировщиками (как планировщик процессов ядра, так и для «зеленых» потоков - планировщик библиотеки потоков).

Если не указано иное (флаг O_DIRECT open или аналогичный,если поддерживается), read() и write() работают с буферами ядра, а read() будет использовать загруженный буфер вместо чтения диска снова.

Обратите внимание, что это может быть затруднено локальной буферизацией файла;например, stdio и iostreams будут считывать данные файла блоками в буфер в процессе, который не зависит от буферов ядра, поэтому write() из другого места в данные, которые уже буферизированы в stdio, не будетвидел.Аналогично, с буферизацией вывода не будет никакого фактического вывода на уровне ядра, пока выходной буфер не будет очищен, либо автоматически, потому что он заполнен, либо вручную из-за fflush() или C ++ endl (который неявно очищает буфер вывода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...