【发布时间】:2017-05-02 18:13:42
【问题描述】:
我有一块可供多个进程访问的共享内存。
对于这块内存,我有一个写入/更新信息的进程(我称之为发布者),并且我有多个进程正在读取这些数据(我称之为订阅者)。
这让我相信,因为我不希望订阅者在发布者的写入/更新过程中读取,我需要实现访问控制,以保证当前在共享内存中的数据完全在订阅者接受之前更新(在写入过程中不读取)。
这是我试图设计的行为:
- 发布者可以修改共享内存,但前提是当前没有其他订阅者正在从内存中读取。
- 任何订阅者都可以从共享内存中读取,只要发布者当前没有修改它。
- 订阅者不能修改共享内存,只能读取;因此,允许消费者并发读取(假设发布者没有修改共享内存)。
我想到的第一个解决方案是一个简单的互斥体,或大小为 1 的信号量。这意味着每次订阅者想要获取新信息时,他们都需要等待发布者更新内存。但是,这会带来意想不到的后果,即订阅者必须等待其他订阅者,并且如果系统上存在足够多的订阅者,发布者可能会延迟或无法发布新数据。
我想到的第二个解决方案是查看 shm 并找到 SHM_LOCK 和 SHM_UNLOCK,这对于强制执行发布者和订阅者角色似乎很有用,但除此之外,似乎只是有助于强化他们可以做的什么,而不一定是何时他们可以做到。
另外,我在其他地方有相反的情况,上面的订阅者成为发布者,每个发布者可能会或可能不会将共享内存块设置为特定值。 (不保证它们会写入内存块,但如果它们确实写入,则可以保证跨发布者的值相同。)上面的发布者成为订阅者。
附录:
- 每个发布者和订阅者都是一个单独的进程。
- 我的问题中的“共享内存”代表多个不同的内存缓存,而不是单个单元。当我的发布者仅对 N 个数据单元中的一个发布更新时,我不希望订阅者锁定所有共享内存。
- 发布者(从第一部分开始)是一个守护进程。我的逻辑是我希望守护进程及时采取行动,将数据放在某个地方;我不希望守护进程在很大程度上受到订阅者的干扰。
我的问题:
- 是否有可以正确编码上述逻辑的控制方案? (发布者设置和删除访问权限,订阅者在可访问时读取。)
- 在这种情况下,是否有更好的方法将信息发布到多个进程?或者在这种情况下共享内存是可行的方法吗?
【问题讨论】:
-
有一个 good tutorial here 讨论同步和信号量。