标题说明了一切。假设我有一个文件,多个进程想要使用我的库修改该文件。防止损坏的传统方法是使用
flock
或类似方法在文件上放置咨询锁。每个进程都尝试打开文件并获取锁;如果无法获得锁,则会阻塞或出错。
现在,假设我想在文件中间插入一行。执行此操作的规范“安全”方法是创建第二个文件,然后在完成所有写入后将其移至第一个文件。
在上述情况下,原始文件上的任何现有文件锁会发生什么情况?由于底层
struct dirent
没有改变(不包括创建/修改时间戳),它们是否被保留?发生这种情况时,在 flock
上阻塞的任何其他进程会发生什么情况?不幸的是,flock
手册页对这些主题保持沉默。
最后,如果上述操作导致锁丢失,有什么好的办法可以代替
flock
来防止并发修改呢?
锁与索引节点相关,而不是与文件名相关。因此,如果你对
file1
有锁,然后执行mv file1.new file1
,旧的file1
的索引节点不会改变(如果有其他硬链接,它们仍然引用原始文件),并且现在的文件名file1
指向file1.new
的inode。
因此,所有文件锁仍然保留在原始文件上。即使没有文件名引用它,只要有任何打开的文件句柄指向它,文件内容就会继续存在。