2009-07-24 46 views
7

我的場景:一臺服務器和一些客戶端(雖然不是很多)。服務器一次只能響應一個客戶端,因此它們必須排隊。我正在使用一個互斥體(boost::interprocess::interprocess_mutex)來做到這一點,包裝在boost::interprocess::scoped_lock如何取得廢棄的boost :: interprocess :: interprocess_mutex的所有權?

問題是,如果一個客戶端在持有該互斥體時意外死亡(即沒有析構函數運行),則其他客戶機遇到麻煩,因爲他們正在等待該互斥體。我考慮過使用定時等待,所以如果我的客戶端等了20秒,並且沒有得到互斥量,它就會繼續向服務器通話。

這種方法的問題:1)它每次都這樣做。如果它在一個循環中,不斷與服務器交談,則需要每次都等待超時。 2)如果有三個客戶端,其中一個客戶端持有互斥鎖,另外兩個將等待20秒,同時與服務器通話 - 正是我試圖避免的。

那麼,我該怎麼對一個客戶說呢,「嘿嘿,看來這個互斥已經被拋棄了,取得它的所有權」?

+2

如果您依賴客戶端進行同步,則會向後執行。你真的應該修復你的服務器,以便它可以接受多個連接,即使它只是讓其他連接等待,而一次只能服務一個連接。這可以讓你從等式中取出* interprocess *部分。 – 2009-07-24 19:42:31

+0

公平點。然而,我的應用程序最初被指定爲一次只有一個客戶端 - 我最近(如今天)發現可能有多個客戶端。我試圖以簡單的方式解決它,但我想我必須想出更復雜的東西。 – 2009-07-24 19:56:10

回答

6

不幸的是,這並不支持boost :: interprocess API原樣。但有幾種方法可以實現它:

如果您在POSIX平臺上支持pthread_mutexattr_setrobust_np,請編輯boost/interprocess/sync/posix/thread_helpers.hpp和boost/interprocess/sync/posix/interprocess_mutex。 hpp使用健壯的互斥體,並以某種方式處理EOWNERDEAD從pthread_mutex_lock返回。

如果您在其他平臺上,可以編輯boost/interprocess/sync/emulation/interprocess_mutex.hpp以使用生成計數器,鎖定標誌位於較低位。然後,您可以創建一個回收協議,該協議將在鎖定字中設置一個標誌以指示未決的回收,然後在超時後執行比較和交換以檢查同一代是否仍在鎖定字中,如果是,則替換它具有鎖定的下一代值。

如果你在windows上,另一個不錯的選擇是使用本地互斥對象;無論如何,他們可能比忙碌更有效率。

您可能還想重新考慮使用共享內存協議 - 爲什麼不使用網絡協議呢?

相關問題