【问题标题】:Access control for one Publisher and multiple Subscribers一个发布者和多个订阅者的访问控制
【发布时间】:2017-05-02 18:13:42
【问题描述】:

我有一块可供多个进程访问的共享内存。

对于这块内存,我有一个写入/更新信息的进程(我称之为发布者),并且我有多个进程正在读取这些数据(我称之为订阅者)。

这让我相信,因为我不希望订阅者在发布者的写入/更新过程中读取,我需要实现访问控制,以保证当前在共享内存中的数据完全在订阅者接受之前更新(在写入过程中不读取)。

这是我试图设计的行为:

  • 发布者可以修改共享内存,但前提是当前没有其他订阅者正在从内存中读取。
  • 任何订阅者都可以从共享内存中读取,只要发布者当前没有修改它。
  • 订阅者不能修改共享内存,只能读取;因此,允许消费者并发读取(假设发布者没有修改共享内存)。

我想到的第一个解决方案是一个简单的互斥体,或大小为 1 的信号量。这意味着每次订阅者想要获取新信息时,他们都需要等待发布者更新内存。但是,这会带来意想不到的后果,即订阅者必须等待其他订阅者,并且如果系统上存在足够多的订阅者,发布者可能会延迟或无法发布新数据。

我想到的第二个解决方案是查看 shm 并找到 SHM_LOCKSHM_UNLOCK,这对于强制执行发布者和订阅者角色似乎很有用,但除此之外,似乎只是有助于强化他们可以做的什么,而不一定是何时他们可以做到。

另外,我在其他地方有相反的情况,上面的订阅者成为发布者,每个发布者可能会或可能不会将共享内存块设置为特定值。 (不保证它们会写入内存块,但如果它们确实写入,则可以保证跨发布者的值相同。)上面的发布者成为订阅者。

附录:

  • 每个发布者和订阅者都是一个单独的进程。
  • 我的问题中的“共享内存”代表多个不同的内存缓存,而不是单个单元。当我的发布者仅对 N 个数据单元中的一个发布更新时,我不希望订阅者锁定所有共享内存。
  • 发布者(从第一部分开始)是一个守护进程。我的逻辑是我希望守护进程及时采取行动,将数据放在某个地方;我不希望守护进程在很大程度上受到订阅者的干扰。

我的问题:

  1. 是否有可以正确编码上述逻辑的控制方案? (发布者设置和删除访问权限,订阅者在可访问时读取。)
  2. 在这种情况下,是否有更好的方法将信息发布到多个进程?或者在这种情况下共享内存是可行的方法吗?

【问题讨论】:

标签: c linux


【解决方案1】:

您需要的是read-write lock

带有pthread_rwlock_* 的pthreads 原生支持这些。 pthread.h。通常 pthreads 将用于线程。

在多个进程的情况下,您可以使用信号量实现读写锁。多做一点阅读和研究,剩下的就很容易自己弄清楚了。

【讨论】:

  • 这确实是我想要的!我认为这样的事情应该很简单,因为这绝对不是什么奇怪的独特问题。既然您提到了信号量,我可以看到您将如何为进程实现一些东西:让一个信号量大小为 N(对于订阅者),一个大小为 M(对于发布者)。订阅者调用方法并请求读取访问权限,发布者调用并请求写入访问权限。检查读取信号量和写入信号量以确定访问权限之间的逻辑和映射。
  • 是的,这很标准。还有很多其他的模式
【解决方案2】:

通常,您需要 两个 mutexes (或更准确地说,两个conds,可以共享相同的mutex)原因是只有锁定访问权限复杂的条件容易出现读者不断重叠并阻止对作者的访问的问题。当使用两个conds时,可以优先考虑写入队列,当有写入等待获取时,不允许阻塞读取资源。好吧,我假设作者的数量远远少于读者的数量,因为你可以打到另一边,并阻止读者,因为作者重叠并阻止他们......

最灵活的方法可能是允许写入者和读取者使用触发器按顺序操作(好吧,读取器可以并行执行),并在另一端有工作人员等待访问时立即准备开关。

无论如何,正如您在其他回复中所建议的那样,请查看其他回复中建议的read-write lock

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多