如何使用Delphi管理从多个EXE实例对XML文件的并发输入/输出访问。

如何使用Delphi管理从多个EXE实例对XML文件的并发输入/输出访问。,xml,delphi,mutex,Xml,Delphi,Mutex,我有一个用Delphi编写的命令行工具,它的任务是在XML文件中插入一个节点,然后立即退出。我需要使该工具的多个实例能够同时执行,并将节点插入到同一个XML中 为了达到这个目的,我引入了一个简单的文件“mutex”——该工具在写入XML之前创建一个临时文件,然后在完成编辑后删除临时文件。因此,如果执行另一个实例,它将检查该临时文件是否存在,并等待它被删除。然后再次创建临时文件,写入XML并删除临时文件 问题是,只有当2-3个实例试图同时写入XML文件时,这种方法才能正常工作。当有更多的实例时,其

我有一个用Delphi编写的命令行工具,它的任务是在XML文件中插入一个节点,然后立即退出。我需要使该工具的多个实例能够同时执行,并将节点插入到同一个XML中

为了达到这个目的,我引入了一个简单的文件“mutex”——该工具在写入XML之前创建一个临时文件,然后在完成编辑后删除临时文件。因此,如果执行另一个实例,它将检查该临时文件是否存在,并等待它被删除。然后再次创建临时文件,写入XML并删除临时文件

问题是,只有当2-3个实例试图同时写入XML文件时,这种方法才能正常工作。当有更多的实例时,其中一些实例会一直等待,并且永远不会将节点附加到XML中


有没有更好的方法使它能够处理大量同时运行并写入XML的实例?

1-设置一个记录挂起更改的文件(它将像队列一样工作)

2-编写一个简单的应用程序来查看该文件,并将更改应用于XML文件

3-修改当前命令行工具,将其更改请求附加到“挂起的更改”文件中


现在只有一个应用程序需要接触最终的XML文件。

TXMLDocument已经阻止多个实例同时写入同一个文件。所以我猜你的问题的真正意思是,“我如何打开一个XML文档进行读取,如何防止其他实例在读取时写入该文档,然后在允许其他实例执行相同操作之前写入该文档?”

在这种情况下,您应该自己打开和关闭文件,而不是让TXMLDocument为您打开和关闭文件。使用TFileStream以独占读写锁和XMLDocument.LoadFromStream(而不是LoadFromFile)打开文件。重置流后使用SaveToStream保存文档。位置为0。使用try/finally以确保在完成流时关闭它。由于您以独占方式锁定文件,因此不再需要临时文件或任何其他类型的互斥锁


显然,如果另一个实例当前正在读取/写入该文件,则打开该文件可能会失败。因此,您需要处理此问题并稍后重试。

请记住,每次需要添加节点时,必须重新加载并重新解析整个文档。根据XML文档的大小和保存的数据,它可能不是传输数据的最有效方法


编写一个单独的文件的方法是一个有趣的解决方案,要考虑的是让你的“多实例”应用程序编写独特的XML文件,然后使用FIDFILL循环将这些文件加载到一个独立的程序中。这样,您就可以保持xml结构几乎完好无损,而不会对现有程序进行任何重大更改。

一个命名的信号量或互斥量可以在一台机器上为您做到这一点。使用SyncObjs中的TMutex,并使用一个接受name参数的构造函数。如果在所有应用程序中使用相同的名称,它们将在同一内核互斥体上同步。使用TMutex.Acquire进行访问,完成后使用TMutex.Release,并在try/finally块中进行保护

使用带有InitialOwner参数的TMutex.Create重载,但为此指定False(当然,除非您想立即获取互斥)。此重载在幕后调用CreateMutex。有关更多详细信息,请查看SyncObjs的源代码和文档。

来源:

在Windows上,如果您可以控制两个程序,则这是可能的。 洛克菲利克斯。对于读取,请在lockfile上打开共享锁。对于写作, 在锁文件上打开独占锁。在Windows中锁定很奇怪, 因此,我建议为此使用单独的锁文件

(“两个程序”不适用于您的情况,因为它是同一个程序,只是在多个实例中运行。)


旁注/我是如何找到这个答案的:Java日志库使用特定于平台的文件锁定API(通过NIO)要实现“”,多个进程可以登录到同一个文件而不会损坏它—这是Delphi RTL文件操作无法实现的。

创建一个目录,将所需的更改作为单独的文件添加到其中可能更容易。然后就没有要附加的文件了,只需删除并运行。但是所有实例都应该再次写入同一个挂起的更改文件。这只会将问题转发到另一个文件。关于目录的想法实际上是可行的。谢谢大家迄今为止的答案。首先,我的代码中有一个逻辑错误,我已经纠正了它,但我使用的方法仍然不好。下周我将继续使用这个小工具,然后我将在这里编写更新,并接受最合适的答案看起来客户机/服务器解决方案非常适合这里…最后我再次循环到此项目,在互斥锁处解决了问题。10x:)