如何同步访问 NAS 上文件的两个进程?

发布于 2024-07-12 12:08:32 字数 160 浏览 9 评论 0原文

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

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

Here's the thing: I have two applications, written in C++ and running on two machines with different OS (one Linux and one Windows). One of this process is in charge of updating an XML file on a NAS (Network Attached Storage) while the other one reads this file.

Is it possible to synchronize these two processes in order to avoid reading of the file at the same time it's being modified?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

作业与我同在 2024-07-19 12:08:32

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

编辑:为了解决注释,您可以实现双重检查锁定类型模式。 让读取器和写入器都有一个锁定文件,并在工作之前仔细检查,例如:

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

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

这将阻止您的进程相互干扰,但可能会出现潜在的竞争条件,因为您可能会同时检查、创建然后重新检查两个进程,尽管这不会导致数据以不一致的状态读取,但会导致同时读取并编写进程以在指定的延迟时间内中止

You could create a lock file on the server that is created before you do a write, wait then write and delete on completion., Have the read process check for the token before reading the file.

Edit: To address the comments, you can implement a double-checked locking type pattern. Have both reader and writer have a locking file and double check before you do work, something like:

Reader: Check for write lock file, create read lock file, check for write lock file, if exists delete read file and abort.

Writer: Check for read lock file, create write lock file, check for read lock file, if exists delete write lock file and abort.

This will stop your processes trampling on each other but a potential race condition may occur in that the you could potentially have both processes check, create then recheck simultaneously though this will not cause the data to be read in an inconsistent state but will cause both read and write processes to abort for your specified delay

童话里做英雄 2024-07-19 12:08:32

谢谢大家的答案。

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

Thank you all for your answers.

At last we managed to resolve our problem, not by using locking commands of the OS (because we were not sure they would propagate correctly to the OS of the NAS head), but by creating lock directories instead of lock files. Directory creation is an atomic operation, and returns an error value if the folder already exists. Therefore, we don't have to check the lock existence before acquiring it, both operations are made in a single step.

花海 2024-07-19 12:08:32

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

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

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

func() 提供共享锁(或 READ 锁)和排他锁(或 WRITE 锁)。 集群将阻塞你的线程(以非繁忙的方式),直到文件被用户解锁(它还提供非阻塞检查,以便你可以在等待时做其他事情)。

查看手册页第 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.

OK you need some form of locking mechanism to control accesses.

Most *nix File systems provide this. I suspect it is also available on Windows File System (as this mechanism is used by perl) but it may have another name.

Take a look at the flock().
This is a file locking mechanism. It is an advisory lock so it does not actually lock the file and prevent usage but it provides a mechanism for marking the file. If both applications use the mechanism then you can control accesses to the file.

flock() provides both shared locks (or READ Lock) and exclusive locks (or WRITE Lock). flock will block your thread (in a non busy way) until the file has been unlocked by the user (it also provides NON blocking checks so you can do other things while waiting).

Check out flock in section 2 of the man pages.

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.
顾北清歌寒 2024-07-19 12:08:32

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

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

If the files reside on an NFS share you can use fcntl(2) to lock the file. Check question D10 in the Linux NFS FAQ. I have very little experience with windows APIs but from what I've heard they have good POSIX support so you should be able to use fcntl as long as they support POSIX.1-2001.

If you are accessing the files using different protocols (i.e. AFS or SMB) maybe you could set up a simple synchronization server that manages locks via an IPC interface?

煞人兵器 2024-07-19 12:08:32

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

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

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

Would it be possible to switch from files to a database?

This type of concurency is something that DBMSs manage very well. It need no be expensive or difficult to install. MySql, Postgress or JavaDB would all handle this elegantly at little or no cost.

Failing the database option I would have the writing process write to a "hidden" file name like ".updateinprogress.xml" and rename the file when the update is complete. On most systems "mv" or "ren" is an atomic operation so the reading process either picks up hte old file or the newer file but never a half written one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文