Подтвердить что ты не робот

Является ли rename() атомарным?

Я не могу проверить это с помощью экспериментов и не могу собрать это со страниц руководства.

Скажем, у меня есть два процесса, один перемещает (переименовывает) файл1 из каталога1 в каталог2. Скажем, другой процесс, выполняющийся одновременно, копирует содержимое directory1 и directory2 в другое место. Возможно ли, что копия произойдет таким образом, что и directory1, и directory2 покажут file1 - то есть directory1 копируется перед перемещением, а directory2 - после перемещения первым процессом.

По сути, является ли rename() атомным системным вызовом?

Спасибо

4b9b3361

Ответ 1

Да и нет.

rename() является атомарным, предполагая, что ОС не сбой. Он не может быть разделен никакими другими файловыми операциями.

Если система выйдет из строя, вы можете увидеть операцию ln().

Также обратите внимание, что при работе в сетевой файловой системе вы можете получить ENOENT, когда операция успешно завершилась. Локальная файловая система не может этого сделать.

Ответ 2

Это очень поздний ответ, но... да rename() является атомарным, но не в смысле вашего вопроса. В разделе Linux rename(2) говорится:

Однако при перезаписи, вероятно, будет окно, в котором оба oldpath и newpath ссылаются на переименованный файл.

Но rename() по-прежнему является атомарным в очень важном смысле: если вы используете его для перезаписи файла, тогда вы получите либо старую, либо новую версию, и ничего больше.

[ update:, но, как указывает @jonas-wielicki в комментариях, вам нужно убедиться, что файл, который вы переименовываете, на самом деле имеет актуальное содержимое, используя fsync() и друзей.]

Если новый путь уже существует, он будет заменен атомом (при условии несколько условий; см. ниже ОШИБКИ), так что нет смысла другой процесс, пытающийся получить доступ к newpath, не обнаружит его.

Если вы видите ОШИБКИ, вы обнаружите, что переименование может потерпеть неудачу, но оно никогда не нарушит атомарность.

Все это на странице руководства Linux. Я не знаю, если вы делаете rename() в сетевой файловой системе, где на сервере работает другая ОС. Есть ли у клиента надежды в аду, гарантирующего атомарность? Я в этом сомневаюсь.

Ответ 3

Я не уверен, что "основная" часть вашего вопроса действительна. Если у вас нет какой-то синхронизации между ними, не имеет значения, как это происходит. Если копия каталога попадает туда до переименования, у вас будет файл1 в обоих местах.

Я не уверен, что вы имели в виду поток или процессы, но если есть механизмы блокировки для обоих, блокировки потоков являются самыми простыми, потому что им не нужно пересекать границы процесса.

Ответ 4

Руководство GNU Libc говорит

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

Ответ 5

Чтобы проверить это, попробуйте использовать strace, чтобы просмотреть все системные вызовы.

Хотя, по вашему делу, вы рассмотрели использование символической ссылки? В производственных системах я использую символическую ссылку для обозначения сегодняшней даты, так что многопользовательские операции используют правильное значение.