2017-05-02 208 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

相關問題