1
有一個示例代碼在多線程環境中「工作」:在多線程代碼中使用shared_ptr
void CSampleClass::Stop(void) {
if (m_pDB != nullptr) {
... Here is some code
m_pDB->Interrupt();
}
}
,其中
m_pDB
成員聲明爲
boost::shared_ptr<CSampleDatabase> m_pDB;
。
m_pDB
可以在另一個類的方法中重置。這就是爲什麼它被測試不是
nullptr
。由於代碼具有多個線程,因此被另一個線程重置,在
if (...)
和
m_pDB->Interrupt();
之間時,可以是
情況。結果是相當戲劇性的。爲了防止出現這種情況,我使用以下代碼修改
void CSampleClass::Stop(void) {
auto pDb = m_pDB; //lock
if (pDb != nullptr) {
... Here is some code
pDb->Interrupt();
}
}
,即如果調用了
m_pDB.reset();
,則在銷燬
pDb
之前,對象永遠不會被釋放。
的問題是:
是否有一個「標準」的方式,以防止情況不涉及儲物櫃,互斥,臨界區等?像使用
boost::weak_ptr
來打破循環引用。確保編譯器聲明
pDB
爲boost::shared_ptr<CSampleDatabase>
而不是CSampleDatabase *
?可能是寫decltype(m_pDB) pDb = m_pDB; //lock
更安全嗎?
第二個版本仍然包含競爭條件。複製構建'shared_ptr'不是一個原子操作。 – Mankarse 2012-03-24 08:28:22
@Mancarse:引用? – 2012-03-24 08:49:54
@nm:從[here](http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety):「shared_ptr對象提供與內置相同級別的線程安全性類型」。這意味着多個'shared_ptr'實例引用同一對象並同時修改這些'shared_ptr'是安全的,但同時修改/讀取一個'shared_ptr'實例並不安全。 – Mankarse 2012-03-24 09:05:59