std::unique_lock<T>
定義了一個移動構造函數,可以隨意使用,但這種方法本身並不是非常成功。 您應該檢查您的鎖定粒度,通常如果您無法提供內部同步並要求用戶在對某個對象執行操作(或需要執行多個操作時)時保持鎖定狀態,則沒有理由將該互斥鎖存儲在目的。
如果我不得不店內對象互斥,我會用一些包裝,讓我做到以下幾點:
locking_wrapper<Test> test;
test.do_locked([] (Test & instance) {
/* The following code is guaranteed not to interleave with
* any operations performed on instance from other threads. */
// your code using instance here
});
的locking_wrapper<T>
將存儲存儲內的對象的實例,並提供一個參考它同時保持對內部互斥鎖的鎖定。依靠編譯器內聯代碼的能力,這種方法不應該超出你想要解決的問題。
上實現locking_wrapper
總體思路如下:
template<typename T>
class locking_wrapper
{
mutable std::mutex mutex;
// the object which requires external synchronization on access
T instance;
public:
/* Here we define whatever constructors required to construct the
* locking_wrapper (e.g. value-initialize the instance, take an
* instance passed by user or something different) */
locking_wrapper() = default;
locking_wrapper(const T & instance) : instance{instance} {}
// Takes a functor to be performed on instance while maintaining lock
template<typename Functor>
void do_locked(Functor && f) const {
const std::lock_guard<std::mutex> lock{mutex};
f(instance);
}
};
您可以調用任何實體傳遞給do_locked
,你認爲合適,但是是lambda表達式調用它就像我先前建議將給它最好的機會,而不用任何開銷。
請注意,使用這種方法與引用,可移動對象或其他類型,我還沒有預見將需要對代碼進行一些修改。
使用'unique_lock'代替? –
如果我用'lock_guard'替換'lock_guard',我會得到我需要的嗎? – Ufx
如果對象只是從外部鎖定,而不是從內部鎖定,爲什麼互斥體需要在內部聲明? –