Adr*_*ala 24
这是一个非常晚的答案,但是......是rename()
原子的,但不是你的问题.在Linux下, rename(2)
说:
但是,当覆盖时,可能会有一个窗口,其中oldpath和newpath都引用要重命名的文件.
但是rename()
在一个非常重要的意义上它仍然是原子的:如果你用它来覆盖一个文件,那么你最终将使用旧版本或新版本,而不是其他任何东西.
[ 更新:但正如@ jonas-wielicki在评论中指出的那样,您需要确保您重命名的文件实际上具有最新内容,使用fsync()
和朋友.]
如果newpath已经存在,它将被原子替换(受一些条件限制;请参阅下面的错误),这样就没有任何一点可以尝试访问newpath的另一个进程会发现它丢失.
如果您看到ERRORS,您会发现重命名可能会失败,但它永远不会破坏原子性.
这完全来自Linux手册页.我不知道的是,如果你rename()
在服务器运行不同操作系统的网络文件系统上进行操作.客户是否希望保证原子性呢?我对此表示怀疑.
Jos*_*hua 23
是的,不是.
rename()是原子的,假设操作系统没有崩溃.它不能被任何其他文件系统op拆分.
如果系统崩溃,您可能会看到ln()操作.
另请注意,在网络文件系统上运行时,如果操作成功,您可能会获得ENOENT.本地文件系统无法做到这一点.
我不确定你问题的"基本"部分是否有效.除非你们之间有某种同步,否则原子重命名的方式并不重要.如果目录副本在重命名之前到达那里,那么你将在两个地方都有file1.
我不确定你是否意味着线程或进程,但如果两者都有锁定机制,则线程锁是最简单的,因为它们不必跨越进程边界.
归档时间: |
|
查看次数: |
19883 次 |
最近记录: |