Является ли rename () атомарным? - PullRequest
40 голосов
/ 14 августа 2011

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

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

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

Спасибо

Ответы [ 4 ]

24 голосов
/ 03 апреля 2014

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

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

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

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

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

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

24 голосов
/ 14 августа 2011

Да и нет.

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

В случае сбоя системы вы можете увидеть операцию ln ().

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

6 голосов
/ 14 августа 2011

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

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

0 голосов
/ 16 апреля 2019

gnu libc руководство говорит

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...