2017-06-14 62 views
2

我與具有讀取和使用升壓shared_mutex寫一個類中的某些屬性的C++多線程程序工作時的工作情況我應該用owns_lock()函數。程序在執行時會創建一個類A的多個對象實例。這個類A有一個由所有A類對象共享的靜態shared_mutex。如果該類的其中一個屬性需要寫入其中一個對象實例中,則該特定對象實例需要通過將其升級爲唯一鎖來獨佔訪問共享互斥鎖。但是,在這樣做之前,set方法會檢查類實例是否擁有鎖,這對我來說看起來有點奇怪。在什麼有增強共享互斥

這或多或少是一個HPP文件怎麼類的樣子:

#include <boost/thread.hpp> 

class A{ 
    private: 
     //Private methods 
     void setAttribute(boost::upgrade_lock<boost::shared_mutex>& lock, const bool value); 
     //Private variables 
     static boost::shared_mutex mainMutex; 
     mutable bool attribute; 
    public: 
     //... Some public methods using setAttribute 
} 

,這是一個CPP文件怎麼類的樣子:

void A::setAttribute(boost::upgrade_lock<boost::shared_mutex>& lock, const bool value) 
{ 
    (void)lock; 
    assert(lock.owns_lock()); 

    //get exclusive access to the lock 
    const boost::upgrade_to_unique_lock<boost::shared_mutex> ulock(lock); 
    attribute = value; 
} 

所以,我的問題是,爲什麼我會需要檢查傳遞的鎖是否擁有鎖,因爲setAttribute方法是私有的,並且只能由類內的方法使用。有什麼情況我應該考慮這樣做嗎?

+1

'(無效)鎖定;'那是什麼? –

+0

從我見過的關於如何使用shared_mutex的示例中,他們總是調用lock(),然後升級到一個唯一的鎖以獲得獨佔訪問權。因此,'(void)lock'似乎調用一個重載操作符來調用upgrade_lock的lock()函數?然而,我不能100%確定這一點,因爲我還沒有能夠通過迄今爲止所做的研究證實它 –

+0

「從我見過的例子」 - 鏈接? –

回答

0

(void) lock;條件存在,以避免在編譯期間使用類似g++ -DNDEBUG -Wall -Werror -pedantic的事件時出現編譯錯誤。這指示編譯器停止對未使用變量(除其他事項)的所有警告。當程序員不知道變量是否被使用,但不想破壞構建時,這是一種有時在代碼中使用的技術。

owns_lock()的方法指示特定對象已經獲得了鎖的所有權。或者換言之,鎖定對象。如果它是共享鎖,那麼多個對象可以「擁有」它。 '擁有'是被這個對象鎖定的同義詞。如果它是唯一的鎖,那麼只有一個對象可以擁有它。

assert()可能就在那裏建立調試,沒有這些代碼將告吹試圖悄悄升級鎖的唯一鎖;即使在鎖不屬於線程的情況下(例如它被解鎖)也是如此。如果這是真的,那麼升級就會失敗。

例如,如果操作的一些排序如下與assert殘疾發生,代碼將失敗默默:

boost::upgrade_lock<boost::shared_mutex> lock(this->mainMutex); 
lock.unlock(); 
this->setAttribute(lock, false); 

upgrade_lock電話獲得升級鎖的所有權。意思是說有合同說這個對象可以升級鎖。

upgrade_to_unique_lock呼叫通過拖延,直到其他任何共享業主解除鎖定不共享鎖的唯一鎖的實際升級。如果在調用此鎖時該鎖不屬於該對象,則它將悄然無法將鎖升級到唯一鎖。

TLDR;我懷疑作者的意圖是保持互斥代碼私有的類,但希望把在解鎖的情況下斷言()不小心被稱爲地方之前setattribute()