[英]std::scoped_lock behaviour with a single mutex
語境:
我知道自從帶有std::scoped_lock
的c++17到來以來, std::lock_guard
變得有點過時了。
我也知道std::scoped_lock
是首選,因為它可以處理多個互斥體並使用與std::lock
相同的死鎖避免算法。
我在這里對我們只有一個互斥鎖的情況感興趣,因此我們不需要關心避免死鎖。
我從這個答案中讀到:
您可以考慮不推薦使用
std::lock_guard
。std::scoped_lock
的單參數情況可以作為std::scoped_lock
來實現,這樣您就不必擔心可能出現的性能問題。
題:
我想知道這句話有多少是真的。
我的意思是,是否保證(根據標准)使用單個互斥鎖, std::scoped_lock
將被專門化,以便消除由於死鎖避免處理而產生的任何不必要的開銷?
我的想法:
經過對該問題的一些調查,我從cppreference 中找到了以下句子:
如果給出了多個互斥體,則使用死鎖避免算法,就像
std::lock
。
這可以讓我們推斷出這樣的事情不會發生(即如果只給出一個互斥鎖)。
但再一次,這只是一個假設。
從這個c++ 草案中,我沒有看到任何關於這種專業化的明確提及。
我得到的唯一一句話是:
當
sizeof...(MutexTypes)
為1
,提供的Mutex
類型應滿足Cpp17BasicLockable要求。 否則,每個互斥類型都應滿足Cpp17Lockable要求。
(強調我的)
我知道BasicLockable要求要求存在滿足此處定義的條件的lock()
和unlock()
函數。
在另一方面中,可鎖定要求假設與加入的BasicLockable要求try_lock()
其滿足條件,如定義的函數那里。
我知道需要try_lock()
函數才能運行std::lock
使用的死鎖避免算法。
根據上述c++草案摘錄中所述,如果我們只給std::scoped_lock
一個互斥鎖,則不需要try_lock()
函數。
這是否足以推斷/考慮始終定義上述專業化(並且可能表現得像std::lock_guard
會做的那樣)。
我會說是的,但因為我從未看到任何明確提及它,我想知道我是對的還是我錯過了什么?
編輯:
效果:用
tie(m...)
初始化pm
。 然后,如果sizeof...(MutexTypes)
為0
,則沒有效果。 否則,如果sizeof...(MutexTypes)
為1
,則m.lock()
。 否則,lock(m...)
。
(強調我的)
這回答了我的詢問,只有在有多個給定的互斥std::lock
才會調用std::lock
。 在問這個問題之前我應該看到它...
當僅提供一個互斥鎖時,要求std::scoped_lock
行為與std::lock_guard
相同。 因此對單個互斥體的情況有不同的要求。
這可以通過專門化來完成,也可以通過不同的內部機制來完成,只要行為是相同的。
如果您閱讀了lock_guard
的規范(就在scoped_lock
),那應該很清楚。
用 m 初始化 pm。 調用 m.lock()
用 tie(m...) 初始化 pm。 [...] 否則如果 sizeof...(MutexTypes) 為 1,則 m.lock()。 [...]
它沒有明確提到使用lock_guard
但需要具有相同的行為。
該標准很少通過專業化來保證某種優化(值得注意的例子是對不同迭代器類型的專業化和std::vector<bool>
可惡之處)。 為此,有兩種方法:
try_lock
,那么為什么它不應該是有效的。scoped_lock
是否在你的代碼的熱門路徑上,如果你真的認為(並有數據證明) scoped_lock
很慢,那么然后才用lock_guard
替換它並再次測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.