locking - 确保尝试删除文件时未更改该文件

标签 locking posix race-condition filehandle file-descriptor

在 POSIX 环境中,我想从磁盘中删除文件,但在删除之前计算其校验和,以确保它没有更改。锁定足够了吗?我应该打开它,取消链接,计算校验和,然后关闭它(以便操作系统可以删除其 inode )?有什么方法可以确保没有其他进程在该文件上拥有打开的文件描述符?

为了提供一些上下文,该代码执行跨主机的文件同步,如果远程主机删除文件但该文件正在本地更改,则可能会丢失数据。

最佳答案

您的 open、unlink、checksum、close 提案将无法按原样工作,因为如果校验和不匹配,您将陷入困境(没有 POSIX 可移植的方法来创建指向由 给出的文件的链接文件描述符)。更好的变体是重命名、校验和、取消链接、关闭,如果校验和不匹配,它可以让您撤消重命名或重做副本。您仍然需要考虑如果第三个程序同时重新创建了该文件您想要做什么。

POSIX 仅提供协作锁。如果您可以控制可能修改文件的程序,请确保它们使用锁;如果这不是一个选项,那么您将陷入没有锁的困境。

没有可移植的方法来查看哪些进程(甚至是否)打开了文件。在大多数 Unix 系统上,lsof 会向您显示,但这不是通用的、不健壮的(程序可以在 lsof 完成查找后立即打开文件)并且不完整(如果文件通过 NFS 导出,则可能无法了解事件客户端)。

查看其他同步程序正在执行的操作(例如 rsync 和 unison)可能会对您有所帮助。

关于locking - 确保尝试删除文件时未更改该文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3258283/

相关文章:

node.js - 在异步竞赛中使用第一个结果/胜者为王

postgresql - 如果两个进程同时修改两个事务中的数据,并且表存在唯一约束,会发生什么情况?

sql-server - 存储过程导致的转换死锁

c# - 如何锁定多个对象?

arrays - 为什么这个数组检查 key 失败?

c - ubuntu 上的 sem_init 使用 C 语言

c# 线程安全深拷贝

c++ - std::lock_guard 还是 std::scoped_lock?

c++ - C 与 C++ 中的 Pthread 之间的差异

java - 解决 Java Spring 应用程序中的竞争条件的最佳方法是什么?