进程间文件交换:效率和竞争条件

时间:2015-10-29 10:38:16

标签: java file operating-system filesystems ipc

故事:
几天前,我在考虑基于文件交换的进程间通信。假设进程A在其工作期间创建了几个文件,然后进程B读取这些文件。为确保正确写入所有文件,创建一个特殊文件会很方便,该文件的存在将表明所有操作都已完成。

简单的工作流程:
进程A创建文件" file1.txt"
进程A创建文件" file2.txt"
进程A创建文件" processA.ready"

进程B正在等待文件" processA.ready"出现,然后读取file1和file2。

疑惑:
文件操作由操作系统执行,特别是由文件子系统执行。由于Unix,Windows或MacOS的实现可能不同,我不确定文件交换进程间通信的可靠性。即使操作系统能够保证这种一致性,Java中的JIT编译器也可以重新排序程序指令。

问题:
1.操作系统中的文件操作是否有任何实际规范?
2. JIT是否真的允许为单个程序线程重新排序文件操作程序指令? 3.文件交换现在仍然是进程间通信的相关选项,还是无条件地选择TCP / HTTP /等更好?

3 个答案:

答案 0 :(得分:3)

  1. 在这种情况下,您无需了解操作系统详细信息。记录Java IO API以猜测文件是否已保存。
  2. JVM无法重新排序本机调用。它不是明确地用JMM编写的,但暗示它不能这样做。 JVM无法猜测本机调用的影响是什么,并且这些调用的重新排序可能非常慷慨。
  3. 使用文件作为沟通方式有一些缺点:
    1. 使用缓慢的IO
    2. 在您需要的情况下很难将不同机器之间的进程分开(例如,有使用samba的方式,但是非常依赖于平台)。

答案 1 :(得分:2)

  1. 您可以使用Java中的文件监视器(WatchService)在.ready文件出现时接收信号。

  2. 重新排序可能适用但在这种情况下不应该损害您的应用程序逻辑 - 请参阅以下链接: https://assylias.wordpress.com/2013/02/01/java-memory-model-and-reordering/

  3. 我不知道您的数据大小,但我觉得在这种情况下使用Message Queue(MQ)解决方案仍然会更好。使用文件IO是一个相对较慢的操作,可能会降低系统速度。

答案 2 :(得分:1)

在我的一个项目中使用基于文件交换的方法。它基于在进程完成时重命名文件扩展名,以便其他进程可以通过文件名表达式检查来检索它。

  1. FTP进程下载文件并将其名称' .downloaded'
  2. 主要任务处理器搜索目录中的文件' *。已下载'。
    在开始之前,作业更新文件名为' .processing'。
    完成后再更新为“.done”。
    如果出现错误,它会创建一个新的补充文件,其中包含' .error'扩展并将最后处理的行和异常跟踪放在那里。在重试时,如果该文件存在,则读取它并从正确的位置继续。
  3. 定位器流程搜索' .done'并根据其配置移动到备份文件夹或删除
  4. 这种方法在移动运营商网络中的巨大负载下运行良好。

    考虑点是对文件使用唯一名称非常重要。因为移动文件的行为会根据操作系统而改变。
    例如当目标文件相同时,Windows会出错,但是unix会将其删除。