进程间文件交换:效率和竞争条件
Posted
技术标签:
【中文标题】进程间文件交换:效率和竞争条件【英文标题】:Inter-process file exchange: efficiency and race conditions 【发布时间】:2016-01-29 11:01:16 【问题描述】:故事: 前几天在想基于文件交换的进程间通信。假设进程 A 在其工作期间创建了几个文件,然后进程 B 读取这些文件。为了确保所有文件都正确写入,创建一个特殊文件会很方便,该文件的存在将表明所有操作都已完成。
简单的工作流程: 进程 A 创建文件“file1.txt” 进程 A 创建文件“file2.txt” 进程A创建文件“processA.ready”
进程 B 等待文件“processA.ready”出现,然后读取文件 1 和文件 2。
疑问: 文件操作由操作系统执行,特别是由文件子系统执行。由于 Unix、Windows 或 MacOS 中的实现可能不同,我不确定文件交换进程间通信的可靠性。即使 OS 会保证这种一致性,Java 中也有 JIT 编译器之类的东西,它可以重新排序程序指令。
问题: 1. 操作系统中的文件操作有没有真正的规范? 2. JIT真的允许为单个程序线程重新排序文件操作程序指令吗? 3. 现在文件交换仍然是进程间通信的一个相关选项还是无条件选择TCP/HTTP/etc?
【问题讨论】:
您将遇到的大问题是磁盘操作的缓存。 如果我是你,我会实现 HTTP。无需同步进程和编写某种事件监听器。将来将这些过程分离到不同的机器上会更容易。 @gkiko 实际上我已经这样做了:) @AdamSkywalker 你想用ipc解决什么问题?在任何情况下,文件系统都将是最慢的:/ @gkiko 在两个进程之间传递文件内容和元数据 【参考方案1】:-
在这种情况下,您无需了解操作系统详细信息。记录了 Java IO API 以猜测文件是否已保存。
JVM 无法重新排序本机调用。它没有明确地用 JMM 编写,但暗示它不能这样做。 JVM 无法猜测本机调用的影响是什么,并且这些调用的重新排序可能非常慷慨。
使用文件作为通信方式有一些缺点:
-
它使用的 IO 很慢
很难在不同机器之间分离进程以备不时之需(例如,有使用 samba 的方法,但完全依赖于平台)
【讨论】:
【参考方案2】:当您的 .ready 文件出现时,您可以使用 Java 中的文件观察器 (WatchService) 来接收信号。
可以应用重新排序,但在这种情况下它不应该损害您的应用程序逻辑 - 请参阅以下链接: https://assylias.wordpress.com/2013/02/01/java-memory-model-and-reordering/
我不知道您的数据大小,但我觉得在这种情况下使用消息队列 (MQ) 解决方案会更好。使用文件 IO 是一个相对较慢的操作,可能会降低系统速度。
【讨论】:
【参考方案3】:在我的一个项目中使用了基于文件交换的方法。它基于在进程完成时重命名文件扩展名,以便其他进程可以通过文件名表达式检查来检索它。
-
FTP 进程下载文件并将其命名为“.downloaded”
主任务处理器在目录中搜索文件“*.downloaded”。
在开始之前,作业将文件名更新为“.processing”。
完成后更新为“.done”。
如果出现错误,它会创建一个带有“.error”扩展名的新补充文件,并将最后处理的行和异常跟踪放在那里。重试时,如果此文件存在,则读取它并从正确位置恢复。
定位器进程搜索“.done”并根据其配置移动到备份文件夹或删除
这种方法适用于移动运营商网络中的巨大负载。
注意点是对文件使用唯一名称很重要。因为移动文件的行为会根据操作系统而变化。 例如当目标位置有相同的文件时,Windows 会报错,但是 unix ovrwrites 它。
【讨论】:
以上是关于进程间文件交换:效率和竞争条件的主要内容,如果未能解决你的问题,请参考以下文章