2014-01-14 58 views
2

我有一些對象,每個與boost :: shared_mutex(我需要共享/唯一鎖定功能)相關聯。std :: lock()相當於boost :: shared_mutex?

在某些代碼中,我需要一次獲得多個對象的唯一所有權。

for (FileMetaData* entry : smd->fileSet) { 
    entry->fileMutex.lock(); 
} 

// some critical work 

for (FileMetaData* entry : smd->fileSet) { 
    entry->fileMutex.unlock(); 
} 

做這樣的事情會導致死鎖,當不同的線程試圖獲得不同的鎖集。

我發現std :: lock()適合我的用例。但是boost :: shared_mutex是否等價?

編輯:

關於有序鎖定模式,這不正是我的情況下工作:

T1 lock (C,D,E) 
T2 wants to lock (B,D), but can only obtain the lock for B 
T1 spawns T3 which works on (B,C), it stuck when obtaining the lock for B 

所以問題是,當T1滋生T3基於B額外的鎖是必需的,這打破了有序的鎖定模式。我認爲這個問題可以解決,如果T2沒有鎖定B鎖定,當D不鎖定,基本上是什麼std ::鎖定。

+0

如果你知道哪些鎖定你需要一次全部 - 即你之前手上整個集合你開始鎖定 - 只需使用任何標準對鎖進行排序並按順序鎖定它們。只要所有線程都遵守相同的鎖定順序,它們就永遠不會死鎖。 (這有時被稱爲「有序鎖定模式」。) – Nemo

+0

@Nemo:下面是各種多鎖算法的性能比較,包括排序算法:http://howardhinnant.github.io/dining_philosophers.html –

回答

1

可以使用std::lock(或等價boost::lock,統稱爲「鎖定功能」)進行共享所有權的鎖定,以及獨佔鎖定,這取決於你在傳遞被鎖定 - 任何Lockable會工作。例如,如果你想鎖定2 std::mutex/boost::mutex小號A, B並以獨佔模式boost::shared_mutex SM,您只需通過三到std::lock

std::lock(A, B, SM); 

,如果你不是想鎖定在共享所有權模式SM,你可以爲它創建一個解鎖boost::shared_lock,並通過進入鎖定功能:

boost::shared_lock<boost::shared_mutex> bsl{SM, boost::defer_lock}; 
std::lock(A, B, bsl); 

在無關你的問題的說明 - 風格偏好 - 我寧願永遠ç onstruct RAII鎖進入std::lock所以我不能搞砸解鎖,所以我其實寫:

auto alk = boost::make_unique_lock(A, std::defer_lock); 
auto blk = boost::make_unique_lock(B, std::defer_lock); 
// boost::make_shared_lock(), where are you?!? 
boost::shared_lock<boost::shared_mutex> bsl{SM, boost::defer_lock}; 
std::lock(alk, blk, bsl); 
+0

謝謝。我還有一個問題。在我的示例代碼中,您可以看到每個互斥量都存儲在FileMetaData結構中,該結構的指針位於fileSet中。我應該如何提取這些互斥變成std :: lock的參數? – Jeremy

+0

除了Casey發佈的內容外,請注意C++ 14已經包含了std :: shared_mutex和std :: shared_lock,這幾乎與boost相同。鏗鏘/海灣合作委員會已經實施了。 – user534498

相關問題