7

我目前正在通过内存映射在多个进程之间共享数据(<1KB)。1个“writer”进程和多个“reader”进程都mmap同一个文件。

目前,阅读器进程需要不断地检查更新。读取器进程不断轮询 mmap-ed 区域以查看是否写入了任何新数据。

典型用法(和现有实现)
“编写器”进程是一个记录器,它以不规则的时间间隔不断地附加新数据(每个都在新行上)。在任何给定时间点,都可能有一个或多个“读取器”进程对“写入器”进程生成的任何新数据感兴趣。此外,它不是一个无限扩展的文件,而是一个循环缓冲区,即在固定数量的行之后,编写器循环返回并开始用新数据从头开始覆盖文件。此文件中的头字段跟踪最新数据的位置,即当前“头”。

简而言之,系统试图模仿msgsnd()msgrcv()的语义,但有两个额外的警告:

  1. 支持多个“阅读者”
    当“作者”发布单个消息时,应发送多个通知,每个活动“阅读者”1 个。
    --> 当前实现,因为每个“阅读器”不断轮询“头”字段并在其更改时读取新数据。

  2. 持久性(文件支持)
    如果任何“读取器”/“写入器”进程突然终止,恢复系统应该像重新启动进程一样简单。
    --> 目前实现的 IPC 共享数据保存在磁盘上的 mmap-ed 文件中。

什么是
-快速(低延迟)和
-轻量级(低 cpu 使用)替代方案来实现某种事件机制以在每次写入程序修改 mmap-ed 区域时通知读取程序进程?

注意:在读取器进程中,当写入器进程更新 mmap-ed 内存时(即使在调用msync()之后),在 mmap-ed 文件上添加inotify监视不会导致任何事件。

4

2 回答 2

1

在所有阻塞通信中,阅读器获取数据,其他阅读器无法读取。

  • 您可以创建一个阅读器链。这很糟糕,因为在您的情况下,进程可能会突然结束
  • 使用多个管道。每次创建阅读器时,它可以要求作者打开一个管道,然后阅读器可以订阅该管道并读取它。此外,作者可以向读者发送当前数据状态的副本,除非读者可以自己访问它。
  • 使用信号。您可以在每次写入后从写入器向所有读取器发送信号。

一个棘手的问题......这些都是我得到的......

于 2013-06-20T14:58:53.660 回答
1

(贴出实际使用的解决方案,以备日后参考)

使用这个将mmap-ed 文件支持添加到 inotify 的补丁,

  • 阅读器进程可以使用inotify框架
  • 以重要/重要的时间间隔监视 mmap-ed 文件的更改
  • 由调用同一 mmap 文件的编写器进程触发。sync()
于 2017-08-25T03:38:12.967 回答