На самом деле это не проблема.
Да, другой процесс может изменить файл, пока он у вас отображается, и да, возможно, вы увидите изменения. Это даже вероятно, поскольку почти все операционные системы имеют унифицированные системы виртуальной памяти, поэтому, если кто-то не запрашивает небуферизованную запись, нет способа записи, не проходя через буферный кеш, и никоим образом без того, чтобы кто-то держал отображение видя изменение.
Это даже не плохо. На самом деле, было бы неприятнее, если бы вы не могли увидеть изменения. Поскольку файл квази становится частью вашего адресного пространства, когда вы его отображаете, совершенно логично, что вы видите изменения в файле.
Если вы используете обычный ввод-вывод (например, read
), кто-то может изменить файл, пока вы его читаете. Другими словами, копирование содержимого файла в буфер памяти не всегда безопасно при наличии модификаций. Это "безопасно", поскольку read
не приведет к сбою, но не гарантирует, что ваши данные непротиворечивы.
Если вы не используете readv
, у вас нет никаких гарантий относительно атомарности (и даже с readv
у вас нет гарантии, что то, что у вас есть в памяти, согласуется с тем, что находится на диске, или что оно не меняется между двумя вызовами readv
). Кто-то может изменить файл между двумя read
операциями или даже когда вы находитесь в середине этого процесса.
Это не просто то, что формально не гарантируется, но "вероятно, все еще работает" - - наоборот, например под Linux запись очевидно не атомарна. Даже не случайно.
Хорошие новости:
Обычно процессы не просто открывают произвольный случайный файл и начинают писать в него. Когда такое случается, обычно это либо хорошо известный файл, который принадлежит процессу (например, файл журнала), либо файл, в который вы явно указали процессу запись (например, сохранение в текстовом редакторе), либо процесс создает новый файл (например, компилятор создает объектный файл), или процесс просто добавляет в существующий файл (например, журналы БД и, конечно же, файлы журналов). Или процесс может атомарно заменить файл другим (или отсоединить его).
В каждом случае вся пугающая проблема сводится к тому, что «нет проблем», потому что либо вы хорошо осведомлены о том, что произойдет (так что это ваша ответственность), либо все работает плавно, не мешая.
Если вам действительно не нравится возможность того, что другой процесс может записать в ваш файл, пока он у вас отображается, вы можете просто опустить FILE_SHARE_WRITE
в Windows при создании дескриптора файла. POSIX несколько усложняет задачу, поскольку вам нужно fcntl
дескриптор для обязательной блокировки, которая необязательно поддерживается или на 100% надежна в каждой системе (например, в Linux).
person
Damon
schedule
22.01.2014
MAP_PRIVATE
. Это не означает, что предоставьте мне личную копию, это означает, что сделанные мной изменения являются личными для меня. Он имеет те же проблемы с параллелизмом, что и любой другой метод доступа к файлу. - person Petesh   schedule 22.01.2014MAP_PRIVATE
означает дать мне частную копию? На самом деле я процитировал ту часть спецификации, в которой говорится об обратном. Хотя было бы неплохо, если бы существовала опция, которая действительно гарантирует, что сопоставленные страницы не будут изменены другими процессами после обращения к ним. - person Stephan Tolksdorf   schedule 22.01.2014FILE_SHARE_READ
, чтобы другие процессы не могли изменять файл, пока вы его используете. - person Harry Johnston   schedule 23.01.2014