Это не проблема.
Да, другой процесс может изменить файл во время его сопоставления, и, возможно, вы увидите изменения. Это даже , вероятно,, так как почти все операционные системы имеют унифицированные системы виртуальной памяти, поэтому, если вы не запрашиваете небуферизованные записи, нет способа писать, не пройдя через буферный кеш, и никоим образом не будет, если кто-то будет иметь сопоставление, видя изменение.
Это даже не плохая вещь. На самом деле, было бы более тревожным, если бы вы не смогли посмотреть изменения. Так как файл quasi становится частью вашего адресного пространства при его сопоставлении, имеет смысл видеть изменения в файле.
Если вы используете обычный ввод-вывод (например, read
), кто-то все еще может изменить файл во время его чтения. По-разному, копирование содержимого файла в буфер памяти не всегда в безопасности при наличии модификаций. Это «безопасно», поскольку read
не будет разбиваться, но он не гарантирует, что ваши данные согласованы.
Если вы не используете readv
, у вас нет никаких гарантий относительно атомарности (и даже с readv
у вас нет гарантии, что то, что у вас есть в памяти, соответствует тому, что находится на диске, или что оно не меняется между двумя вызовами до readv
). Кто-то может изменить файл между двумя операциями read
или даже когда вы находитесь в середине его.
Этот не является только тем, что официально не гарантировано, но «возможно, все еще работает» - наоборот, например. под Linux пишет явно не атомный. Не случайно.
Хорошая новость:
Обычно процессы не просто открыть произвольную случайную файл и начать запись в него. Когда такое происходит, обычно это либо известный файл, который принадлежит процессу (например, файл журнала), либо файл, который явным образом сказал процессу для записи (например, сохранение в текстовом редакторе), или процесс создает новый файл (например,компилятор, создающий объектный файл), или только процесс добавляет в существующий файл (например, журналы db и, конечно, файлы журнала). Или процесс может заменить файл другим способом (или отменить связь).
В любом случае вся страшная проблема сводится к «нет проблемы», потому что либо вы хорошо знаете, что произойдет (так это ваша ответственность), либо она работает без помех.
Если вы действительно не нравится, вероятность того, что другой процесс может возможно писать в файл, а вы его на карту, вы можете просто опустить FILE_SHARE_WRITE
под Windows, при создании дескриптора файла. POSIX делает его несколько более сложным, так как вам нужно указать fcntl
дескриптор обязательной блокировки, который не обязательно поддерживается или 100% надежен для каждой системы (например, в Linux).
Это возможно для другого процесса изменения файла во время его использования. Картирование памяти - это один из самых разных способов использования файла - он не более опасен, чем любой другой. – Casey
Копирование содержимого файла с помощью обычных API-интерфейсов чтения в буфер памяти всегда безопасно, даже если файл одновременно изменяется. Напротив, если вы получаете доступ к файлу с отображением памяти с помощью обычных указателей, а внешний процесс одновременно его модифицирует, вы получаете неопределенное поведение, потому что это не связано с ограничениями модели памяти C (++).Как правило, если память, которую вы или ваш компилятор ожидаете постоянных изменений под ногами, произойдет плохо. Вход, который вы подтвердите за один момент, может стать недействительным в следующий момент. –
Вы неверно истолковываете цель 'MAP_PRIVATE'. Это не значит, что я даю мне частную копию * это означает, что сделанные мной модификации являются частными для меня **. Он имеет все те же проблемы параллелизма, что и любой другой метод для доступа к файлу. – Petesh