Linux rename() 是原子的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7054844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is rename() atomic?
提问by Lipika Deka
I am not being able to check this via experiments and could not gather it from the man pages as well.
我无法通过实验检查这一点,也无法从手册页中收集它。
Say I have two processes, one moving(rename) file1 from directory1 to directory2. Say the other process running concurrently copies the contents of directory1 and directory2 to another location. Is it possible that the copy happens in such a way that both directory1 and directory2 will show file1 - i.e directory1 is copied before the move and directory2 after the move by the first process.
假设我有两个进程,一个是将文件 1 从目录 1 移动(重命名)到目录 2。假设同时运行的另一个进程将 directory1 和 directory2 的内容复制到另一个位置。复制是否有可能以这样的方式发生,即目录 1 和目录 2 都将显示文件 1 - 即目录1 在移动之前被复制,目录2 在移动之后被第一个进程复制。
Basically is rename() is an atomic system call?
基本上是 rename() 是一个原子系统调用?
Thanks
谢谢
采纳答案by Joshua
Yes and no.
是和否。
rename() is atomic assuming the OS does not crash. It cannot be split by any other filesystem op.
假设操作系统没有崩溃, rename() 是原子的。它不能被任何其他文件系统操作拆分。
If the system crashes you might see a ln() operation instead.
如果系统崩溃,您可能会看到 ln() 操作。
Also note, when operating on a network filesystem, you might get ENOENT when the operation succeeded successfully. Local filesystem can't do that to you.
另请注意,在网络文件系统上操作时,如果操作成功,您可能会收到 ENOENT。本地文件系统不能对你这样做。
回答by boatcoder
I'm not sure the "basically" part of your question is valid. Unless you have some kind of synchronization between the two, it doesn't matter how atomic rename is. If the directory copy gets there before the rename, you are going to have file1 in both places.
我不确定您问题的“基本”部分是否有效。除非您在两者之间有某种同步,否则原子重命名如何无关紧要。如果目录副本在重命名之前到达那里,您将在两个地方都有 file1。
I'm not sure if you meant thread or processes, but if there are locking mechanisms for both, threading locks are by far the simplest because they don't have to cross process boundaries.
我不确定你的意思是线程还是进程,但如果两者都有锁定机制,线程锁是迄今为止最简单的,因为它们不必跨越进程边界。
回答by Adrian Ratnapala
This is a very late answer, but... yes rename()
is atomic but not in the sense of your question. Under Linux, rename(2)
says:
这是一个很晚的答案,但是......是的,rename()
是原子的,但不是你的问题。在 Linux 下, rename(2)
说:
However, when overwriting there will probably be a window in which both oldpath and newpath refer to the file being renamed.
但是,当覆盖时,可能会出现一个窗口,其中 oldpath 和 newpath 都指向被重命名的文件。
But rename()
is still atomic in a very important sense: if you use it to overwrite a file, then you will end up with either the old or the new version and nothing else.
但rename()
在一个非常重要的意义上仍然是原子的:如果你用它来覆盖一个文件,那么你最终会得到旧版本或新版本,没有别的。
[update:but as @jonas-wielicki points out in the comments, you need to make sure the file you are renaming actually has up-to-date contents, using fsync()
and friends.]
[更新:但正如@jonas-wielicki 在评论中指出的那样,您需要确保您正在重命名的文件实际上具有最新的内容,使用fsync()
和朋友。]
If newpath already exists it will be atomically replaced (subject to a few conditions; see ERRORS below), so that there is no point at which another process attempting to access newpath will find it missing.
如果 newpath 已经存在,它将被自动替换(取决于一些条件;请参见下面的错误),因此在另一个尝试访问 newpath 的进程中不会发现它丢失了。
If you see ERRORS, you will find that the rename might fail, but it will never break the atomicity.
如果你看到 ERRORS,你会发现重命名可能会失败,但它永远不会破坏原子性。
This is all from the Linux man page. What I don't know is if you do a rename()
on a network file-system where the server runs a different OS. Does the client have a hope in hell of guaranteeing atomicity then? I doubt it.
这一切都来自 Linux 手册页。我不知道您是否rename()
在服务器运行不同操作系统的网络文件系统上执行操作。那么客户端是否有希望保证原子性呢?我对此表示怀疑。
回答by shaftdiesel
the gnu libc manualsays
gnu libc手册说
One useful feature of rename is that the meaning of newname changes “atomically” from any previously existing file by that name to its new meaning (i.e., the file that was called oldname). There is no instant at which newname is non-existent “in between” the old meaning and the new meaning. If there is a system crash during the operation, it is possible for both names to still exist; but newname will always be intact if it exists at all.
重命名的一个有用功能是,newname 的含义从任何以前存在的文件中“原子地”更改为它的新含义(即,被称为 oldname 的文件)。没有任何时刻新名称不存在“介于”旧含义和新含义之间。如果操作过程中出现系统崩溃,有可能两个名字都还存在;但是如果 newname 存在,它将始终保持不变。