这就是:我有两个应用程序,用C ++编写并在两台具有不同操作系统的机器上运行(一个Linux和一个Windows)。其中一个过程负责更新NAS(网络附加存储)上的XML文件,而另一个过程则读取此文件。
是否可以同步这两个进程以避免在修改文件的同时读取文件?
答案 0 :(得分:8)
您可以在执行写入之前在服务器上创建一个锁定文件,然后在完成时等待写入和删除。在读取文件之前,让读取过程检查令牌。
编辑:要解决注释,您可以实现双重检查锁定类型模式。读者和作者都有一个锁定文件,并在你工作之前仔细检查,例如:
Reader:检查写锁文件,创建读锁文件,检查写锁文件,如果存在则删除读文件并中止。
Writer:检查读取锁定文件,创建写入锁定文件,检查读取锁定文件,如果存在则删除写入锁定文件并中止。
这将阻止您的进程相互踩踏,但可能会出现潜在的竞争条件,因为您可能会检查两个进程,然后创建然后同时重新检查,尽管这不会导致数据以不一致的状态读取但会导致读取和写入进程中止指定的延迟
答案 1 :(得分:5)
谢谢大家的回答。
最后我们设法解决了我们的问题,而不是使用操作系统的锁定命令(因为我们不确定它们是否会正确传播到NAS头的操作系统),而是通过创建锁定目录而不是锁定文件。目录创建是一种原子操作,如果该文件夹已存在,则返回错误值。因此,我们不必在获取之前检查锁存在,两个操作都是一步完成的。
答案 2 :(得分:2)
好的,你需要某种形式的锁定机制来控制访问。
大多数* nix文件系统提供此功能。我怀疑它在Windows文件系统上也可用(因为这个机制由perl使用),但它可能有另一个名称。
看看羊群() 这是一种文件锁定机制。它是一个咨询锁,因此它实际上不会锁定文件并阻止使用,但它提供了一种标记文件的机制。如果两个应用程序都使用该机制,那么您可以控制对该文件的访问。
flock()提供共享锁(或READ Lock)和独占锁(或WRITE Lock)。 flock会阻塞你的线程(以非繁忙的方式),直到文件被用户解锁(它还提供非阻塞检查,以便你可以在等待时做其他事情)。
查看手册页第2部分中的flock。
int flock(int fd, int operation);
Flock() applies or removes an advisory lock on the file associated with the file
descriptor fd. A lock is applied by specifying an operation parameter that is
one of LOCK_SH or LOCK_EX with the optional addition of LOCK_NB. To unlock an
existing lock operation should be LOCK_UN.
答案 3 :(得分:1)
如果文件驻留在NFS共享上,您可以使用fcntl(2)来锁定文件。检查Linux NFS FAQ中的问题 D10 。我对Windows API的经验很少,但据我所知他们有很好的POSIX支持,所以你应该能够使用fcntl,只要它们支持POSIX.1-2001。
如果您使用不同的协议(即AFS或SMB)访问文件,您可以设置一个通过IPC接口管理锁定的简单同步服务器吗?
答案 4 :(得分:1)
是否可以从文件切换到数据库?
这种类型的可靠性是DBMS管理得非常好的。它不需要昂贵或难以安装。 MySql,Postgress或JavaDB都可以很少或免费地处理这个问题。
使数据库选项失败我会将写入过程写入“隐藏”文件名,如“.updateinprogress.xml”,并在更新完成后重命名该文件。在大多数系统中,“mv”或“ren”是一个原子操作,所以读取过程要么选择旧文件,要么选择较新的文件,但不要写一半。