`write` сериализация в POSIX - PullRequest
1 голос
/ 06 января 2020

Я пытаюсь понять это требование в POSIX-2017 :

Записи могут быть сериализованы относительно других операций чтения и записи. Если чтение () данных файла может быть доказано (любым способом) после записи () данных, это должно отражать, что запись (), даже если вызовы выполняются разными процессами. Аналогичное требование применяется к нескольким операциям записи в одну и ту же позицию файла.

1) Относится ли "происходит" к тому, что read вызывается, read успешно возвращается или что-то еще?

2) Если, когда один процесс вызывает read, другой процесс дважды вызывает write для одного и того же файла, существуют ли обстоятельства, при которых чтение будет отражать часть или всю вторую запись, но не всю first?

  |----------------read-----------------|
      |--write1--|       |--write2--|

3) Как это обрабатывается реализациями ( например ext4)? Стоит ли беспокоиться об этом?

1 Ответ

0 голосов
/ 12 января 2020

Чтобы ответить на ваш первый вопрос :

«Происходит» относится ко всему прочтению от точки вызова до точки возвращаемого значения. Все это должно произойти после предыдущей записи и до следующей записи. На той же странице написано так:

После успешного возврата write () в обычный файл:

  • Любое успешное чтение () с каждой позиции байта в файл, который был изменен этой записью, должен возвращать данные, указанные в write () для этой позиции, до тех пор, пока такие позиции байтов не будут снова изменены.

  • Любая последующая успешная запись () в ту же самую Позиция байта в файле должна перезаписывать эти данные файла.

POSIX не дает никаких гарантий при каком-либо чередовании, потому что реализация дополнительных гарантий довольно трудна.

По второму вопросу :

Опять же, обратитесь к приведенной выше цитате. Если процессы с именами write() и write() вернулись успешно, любое последующее чтение любых процессов будет отражать записанные данные.

Таким образом, ответ «да, если первая запись () не удалась».

Реализация :

ext4 и почти любая другая файловая система использует кеш страниц. Кэш страницы представляет собой представление данных файла (или соответствующей их части) в памяти. Любая синхронизация, которая должна быть сделана, выполняется с использованием этого представления. В этом отношении чтение и запись из файла аналогичны чтению и записи из общей памяти.

Кэш страниц, как следует из названия, состоит из страниц. В большинстве реализаций страница представляет собой область памяти размером 4 КБ, и чтение и запись происходят на основе страниц.

Это означает, что, например, ext4 будет сериализовывать операции чтения и записи в той же области 4 КБ файла, но запись 12k не может быть атомом c.

AFAICT, ext4 не разрешает одновременную множественную запись на одной странице или одновременное чтение и запись на одной странице, но это нигде не гарантируется .

edit : Размер блока файловой системы (на диске) может быть меньше, чем страница, и в этом случае некоторые операции ввода-вывода могут выполняться в гранулярность размера блока, но это еще менее надежно с точки зрения атомарности.

...