Toto je velmi pozdní odpověď, ale... ano rename()
je atomový, ale ne ve smyslu vaší otázky. V systému Linux rename(2)
říká:
Při přepisování se však pravděpodobně objeví okno, ve kterém stará cesta i nová cesta odkazují na přejmenovaný soubor.
Ale rename()
je stále atomický ve velmi důležitém smyslu:pokud jej použijete k přepsání souboru, skončíte buď se starou, nebo s novou verzí a ničím jiným.
[aktualizace: ale jak zdůrazňuje @jonas-wielicki v komentářích, musíte se ujistit, že soubor, který přejmenováváte, má skutečně aktuální obsah, pomocí fsync()
a přátelé.]
Pokud nová cesta již existuje, bude atomicky nahrazena (s výhradou několika podmínek; viz CHYBY níže), takže neexistuje žádný bod, kdy by ji jiný proces, který se pokouší o přístup k nové cestě, shledal, že chybí.
Pokud uvidíte CHYBY, zjistíte, že přejmenování může selhat, ale nikdy to nenaruší atomicitu.
To je vše z manuálové stránky Linuxu. Nevím, jestli uděláte rename()
na síťovém souborovém systému, kde na serveru běží jiný OS. Má tedy klient v pekle naději na zaručení atomičnosti? Pochybuji.
Ano a ne.
rename() je atomické za předpokladu, že OS nespadne. Nemůže být rozdělen žádným jiným souborovým systémem op.
Pokud dojde k selhání systému, můžete místo toho vidět operaci ln().
Všimněte si také, že když pracujete na síťovém souborovém systému, můžete dostat ENOENT, když operace byla úspěšná. Místní souborový systém vám to nemůže udělat.
Nejsem si jistý, zda je „v podstatě“ část vaší otázky platná. Pokud mezi nimi nemáte nějakou synchronizaci, nezáleží na tom, jak atomové přejmenování je. Pokud se tam kopie adresáře dostane před přejmenováním, budete mít soubor1 na obou místech.
Nejsem si jistý, zda jste mysleli vlákno nebo procesy, ale pokud pro oba existují zamykací mechanismy, jsou zámky vláken zdaleka nejjednodušší, protože nemusí překračovat hranice procesů.