扭转锁定文件
就像其他答案提到的那样,最简单的方法是在与数据文件相同的目录中创建一个锁定文件。
由于您希望能够通过多台 PC 访问同一个文件,因此我能想到的最佳解决方案是仅包含当前写入数据文件的机器的标识符。
所以写入数据文件的顺序是:
检查是否存在锁定文件
如果有一个锁定文件,通过检查它的内容是否有我的标识符来查看我是否是拥有它的人。
如果是这种情况,只需写入数据文件,然后删除锁定文件。
如果不是这种情况,只需等待一秒钟或一小段随机时间,然后再次尝试整个循环。
如果没有锁定文件,请使用我的标识符创建一个并再次尝试整个循环以避免竞争条件(重新检查锁定文件是否真的是我的)。
除了标识符,我会在锁定文件中记录一个时间戳,并检查它是否早于给定的超时值。
如果时间戳太旧,则假设锁定文件已过时并删除它,因为这意味着写入数据文件的 PC 之一可能已崩溃或其连接可能已丢失。
另一种解决方案
如果你在控制数据文件的格式,可以在文件的开头保留一个结构来记录它是否被锁定。
如果您只是为此目的保留一个字节,您可以假设,例如,这00
意味着数据文件没有被锁定,而其他值将代表当前写入它的机器的标识符。
NFS 的问题
好的,我要添加一些内容,因为 Jiri Klouda 正确地指出NFS 使用客户端缓存,这将导致实际的锁定文件处于未确定状态。
解决这个问题的几种方法:
noac
使用orsync
选项挂载 NFS 目录。这很容易,但不能完全保证客户端和服务器之间的数据一致性,因此可能仍然存在问题,尽管在您的情况下它可能没问题。
O_DIRECT
使用、O_SYNC
或O_DSYNC
属性打开锁定文件或数据文件。这应该完全禁用缓存。
这会降低性能,但会确保一致性。
您可能可以使用flock()
锁定数据文件,但其实现参差不齐,您需要检查您的特定操作系统是否实际使用 NFS 锁定服务。否则它可能什么都不做。
如果数据文件被锁定,那么另一个打开它进行写入的客户端将失败。
哦,是的,它似乎不适用于 SMB 共享,所以最好还是忘记它。
不要使用 NFS,而只使用 Samba:有一篇关于该主题的好文章以及为什么 NFS 可能不是您使用场景的最佳答案。
您还将在本文中找到锁定文件的各种方法。
Jiri 的解决方案也不错。
基本上,如果您想保持简单,请不要将 NFS 用于在多台机器之间共享的频繁更新的文件。
有些不同
使用小型数据库服务器将数据保存到并完全绕过 NFS/SMB 锁定问题,或者保留当前的多个数据文件系统,只需编写一个小实用程序来连接结果。
它可能仍然是解决您的问题的最安全和最简单的解决方案。