2017-05-02 124 views
1

我有一个共享内存块,多进程访问。我有一个写/更新信息(我称之为发布者)的进程,而且我有多个正在读取这些数据的进程(我正在调用订阅者)。一个发布者和多个订阅者的访问控制

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

这是我想要设计的行为:

  • 出版商可以修改共享内存,但只有在没有其他用户正在从内存中读取。
  • 任何订阅服务器都可以从共享内存中读取,只要发布服务器当前未修改它即可。
  • 订户不得修改共享内存,只能读取;因此,允许消费者同时进行阅读(假设发布者不修改共享内存)。

我想到的第一个解决方案是一个简单的互斥量或大小为1的信号量。这意味着每次订阅者想要获取新信息时,他们都需要等待内存被更新出版商。然而,这具有订户不得不等待其他订户的意想不到的后果,并且如果系统上存在足够的订户,则发布者被延迟或锁定在发布新数据的能力之外的可能性。

我想起了一直在寻找进入shm,发现SHM_LOCKSHM_UNLOCK,这似乎强制执行发布服务器和订阅的角色是有用的,但在其他方面似乎只是帮助加强什么他们可以做,而不是第二个解决方案必然他们可以做到这一点。

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

附录:

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

我的问题:

  1. 有没有可以正确编码上面的逻辑控制方案? (发布者设置并删除访问,订阅者在可访问时读取。)
  2. 在这种情况下,是否有更好的方法将信息发布到多个进程?还是共享记忆在这种情况下走的路?
+0

有一个_ [很好的教程](https://www.classes.cs.uchicago.edu/archive/2017/winter/51081-1/LabFAQ/lab7/Semaphores.html)_讨论同步和信号灯。 – ryyker

回答

1

你需要什么被称为read-write lock

这些本地支持pthread与pthread_rwlock_*pthread.h。通常pthreads将用于线程。

在多进程的情况下,你可以实现一个带信号量的读写锁。多做一点阅读和研究,这很容易就可以自己找出其他问题。

+1

这确实是我一直在寻找的!我认为这样的应该是非常简单的,因为这绝对不是一个奇怪的独特问题。现在你提到了信号量,我可以看到你将如何为进程实现一些东西:让一个信号量的大小为N(对于订阅者)和一个大小为M的(对于发布者)。订阅者调用方法并请求读取访问,发布者调用并请求写入访问。检查读取信号量和写入信号量以确定访问之间的逻辑和映射。 – Ryan

+0

是的,这是非常标准的。还有很多其他的模式 – MrJLP

0

通常情况下,你需要为 mutex ES(或者更准确地说,二cond S,即可以共享相同的mutex)的原因是,只有一个复杂的条件锁定ACCES很容易出现一个问题,即读者不断重叠并阻止对作家的访问。当使用两个cond时,您可以优先考虑作家队列,并且在有作者等待获取时不允许阻止阅读资源。那么,我认为作家的人数远远低于读者人数,因为你可以击中另一面,并阻止读者,因为作家重叠并阻止他们......

最灵活的方法可能允许作者和读者按顺序行动(好吧,读者可以并行)使用触发器,并在对方工作人员等待访问时立即准备开关。

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

相关问题