【问题标题】:How can I synchronize two processes accessing a file on a NAS?如何同步访问 NAS 上的文件的两个进程?
【发布时间】:2010-10-03 02:34:46
【问题描述】:

事情是这样的:我有两个应用程序,用 C++ 编写并在两台具有不同操作系统(一台 Linux 和一台 Windows)的机器上运行。其中一个过程负责更新 NAS(网络附加存储)上的 XML 文件,而另一个则读取该文件。

是否可以同步这两个进程以避免在修改文件的同时读取文件?

【问题讨论】:

    标签: c++ concurrency synchronization mutex nas


    【解决方案1】:

    您可以在执行写入之前创建的服务器上创建一个锁定文件,等待然后写入并在完成时删除。在读取文件之前让读取进程检查令牌。

    编辑:要解决 cmets,您可以实现双重检查锁定类型模式。让读者和作者都有一个锁定文件并在工作之前仔细检查,例如:

    Reader:检查写锁文件,创建读锁文件,检查写锁文件,如果存在则删除读文件并中止。

    Writer:检查读锁文件,创建写锁文件,检查读锁文件,如果存在则删除写锁文件并中止。

    这将阻止您的进程相互践踏,但可能会发生潜在的竞争条件,因为您可能会同时检查、创建和重新检查两个进程,但这不会导致数据以不一致的状态读取,但会导致读取和写入进程在您指定的延迟内中止

    【讨论】:

    • 这就是我们使用的简单解决方案,但是您如何确保两个进程不会同时检查文件是否存在,然后愉快地锁定并开始一起写入/读取?
    • 双重检查锁定,有一个用于读取和写入的锁定文件,检查无文件,创建文件,检查无文件然后采取如下操作:en.wikipedia.org/wiki/Double-checked_locking
    • @Wolfwyd。不,*nix 文件系统已经为此内置了功能:执行“man 2 flock()”。在共享和独占模式下提供咨询文件锁。
    【解决方案2】:

    谢谢大家的回答。

    最后我们设法解决了我们的问题,不是通过使用操作系统的锁定命令(因为我们不确定它们是否会正确传播到 NAS 头的操作系统),而是通过创建锁定目录而不是锁定文件。目录创建是原子操作,如果文件夹已经存在则返回错误值。因此,我们不必在获取锁之前检查它是否存在,这两个操作都是一步完成的。

    【讨论】:

      【解决方案3】:

      好的,您需要某种形式的锁定机制来控制访问。

      大多数 *nix 文件系统都提供此功能。我怀疑它在 Windows 文件系统上也可用(因为 perl 使用了这种机制),但它可能有另一个名称。

      看一下flock()。
      这是一种文件锁定机制。它是一种建议锁,因此它实际上不会锁定文件并阻止使用,但它提供了一种标记文件的机制。如果两个应用程序都使用该机制,那么您可以控制对文件的访问。

      flock() 提供共享锁(或读锁)和排他锁(或写锁)。 flock 将阻塞您的线程(以非忙碌方式),直到用户解锁文件(它还提供非阻塞检查,因此您可以在等待时做其他事情)。

      查看手册页第 2 节中的羊群。

      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.
      

      【讨论】:

      • flock 不能保证在与旧版本 Linux 的 NFS 共享上具有预期的行为。
      【解决方案4】:

      如果文件位于 NFS 共享上,您可以使用 fcntl(2) 锁定文件。检查Linux NFS FAQ 中的问题D10。我对 Windows API 的经验很少,但据我所知,它们具有良好的 POSIX 支持,因此只要它们支持 POSIX.1-2001,您就应该能够使用 fcntl。

      如果您使用不同的协议(即 AFS 或 SMB)访问文件,也许您可​​以设置一个简单的同步服务器,通过 IPC 接口管理锁?

      【讨论】:

        【解决方案5】:

        是否可以从文件切换到数据库?

        DBMS 可以很好地管理这种类型的并发性。它不需要昂贵或难以安装。 MySql、Postgress 或 JavaDB 都可以以很少或没有成本优雅地处理这个问题。

        如果数据库选项失败,我会让写入过程写入“隐藏”文件名,如“.updateinprogress.xml”,并在更新完成后重命名文件。在大多数系统上,“mv”或“ren”是一个原子操作,因此读取过程要么选择旧文件,要么选择新文件,但永远不会写一半。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-23
          • 1970-01-01
          • 1970-01-01
          • 2015-07-04
          • 1970-01-01
          • 2021-08-09
          • 2018-10-15
          • 2016-01-07
          相关资源
          最近更新 更多