Я смутно припоминаю, что где-то читал, что в некоторых Unix-системах был способ открыть существующий файл для записи с флагом, который запрашивал у ядра использовать старую версию (для других процессов, обращающихся к ней для чтения), до тех пор, пока «новый msgstr "версия была полностью написана (закрыта), с этого момента файл появился как новая версия.
Другими словами, другие процессы либо видели старую версию, либо новую, а не полностью написанную.
Может ли кто-нибудь знающий указать мне ссылку?
kernel
open-files
eudoxos
источник
источник
Ответы:
То, что вы описываете, звучит так же, как обычное переименование, чтобы перезаписать файл.
Когда вы переименовываете / перемещаете один файл поверх другого, старый файл не связывается. Это означает, что файл все еще существует, но его больше нет в дереве файловой системы. Таким образом, старые приложения будут по-прежнему иметь возможность доступа к файлу, пока они остаются открытыми. После того, как все приложения закрыли старый файл, он фактически не распределяется на диске.
rename
Системный вызов является атомарной операцией. Таким образом, чтобы сделать это, вы должны создать новый файл под другим именем, а затем позвонить,rename
чтобы переименовать временный файл как тот, который вы хотите заменить. Поскольку операция является атомарной, нет абсолютно никакого периода, когда файл отсутствует. Он мгновенно переходит из старого файла в новый файл.Обратите внимание, что временный файл и заменяемый файл должны находиться в одной точке монтирования.
источник
rename
своп. Даже если бы существовала такая «ОС-функция», о которой вы говорите, программу все равно нужно было бы написать, чтобы воспользоваться этой возможностью. Какая разница?open
системному вызову или если вам нужно делать то, что вы описываете вручную.Как пишет Патрик , обычный способ сделать это - записать новую версию в отдельный файл, а по окончании переименовать новую версию в старое имя файла, перезаписав ее атомарно. Эта вторая операция называется перезапись-переименованием .
Теперь несколько ссылок:
ISO C
rename
должен быть атомарным. Из Open Group Base Технические характеристики :Старые версии Mac OS X не имели атомных переименований; по сообщениям, это исправлено в Lion.
Btrfs, очевидно, намеренно нарушает стандарт, не гарантируя атомное переименование по соображениям производительности. Однако перезапись по переименованию все еще атомарна , и это все, что вам нужно для этой цели.
источник
man 3p rename
говорит мне, чтоrename
это действительно атомарно, и я думаю, это предназначено для всех файловых систем Linux. И когда я читаю первую статью, которую вы связали, я все еще думаю, что операции переименования Btrfs являются атомарными.Это напоминает мне о Allocate On Flush . Когда файловая система использует эту функцию, вместо записи данных непосредственно на диск, она вычитает размер данных, которые должны быть записаны, из счетчика свободного пространства на диске и хранит данные в памяти, пока не будет выполнен системный вызов синхронизации или пока ядро не решит очистить грязные буферы.
В этом случае, если файл изменяется одним процессом и открывается другим процессом, последний «увидит» неизмененную ( или «старую», если хотите ) версию файла.
Конечно, вышесказанное является теоретическим и зависит от различных факторов, и я бы сказал, что это немного непредсказуемо, поскольку вы точно не знаете, когда ядро очистит грязные страницы. Например, в Linux ( как вы также можете прочитать в разделе 15.3 «Понимание ядра Linux» ), грязные страницы записываются на диск при следующих условиях:
Кэш страниц переполняется и требуется больше страниц, или количество грязных страниц становится слишком большим.
Слишком много времени прошло с тех пор, как страница осталась грязной.
Процесс запрашивает все ожидающие изменения блочного устройства или определенного файла для сброса; это делается путем вызова системных вызовов sync (), fsync () или fdatasync ().
Известно, что эта функция реализована в файловых системах HFS +, XFS, Reiser4, ZFS, Btrfs и ext4.
источник