[英]Is boost shared_ptr <XXX> thread safe?
我有一個關於boost::shared_ptr<T>
。
有很多線程。
using namespace boost;
class CResource
{
// xxxxxx
}
class CResourceBase
{
public:
void SetResource(shared_ptr<CResource> res)
{
m_Res = res;
}
shared_ptr<CResource> GetResource()
{
return m_Res;
}
private:
shared_ptr<CResource> m_Res;
}
CResourceBase base;
//----------------------------------------------
// Thread_A:
while (true)
{
//...
shared_ptr<CResource> nowResource = base.GetResource();
nowResource.doSomeThing();
//...
}
// Thread_B:
shared_ptr<CResource> nowResource;
base.SetResource(nowResource);
//...
如果Thread_A不關心nowResource
是最新的,那么這部分代碼會有問題嗎?
我的意思是當Thread_B完全沒有SetResource()
, Thread_A通過GetResource()
得到一個錯誤的智能點?
線程安全是什么意思?
如果我不關心資源是否是最新的,那么當nowResource
被釋放時, shared_ptr<CResource> nowResource
會使程序崩潰,或者問題是否會破壞shared_ptr<CResource>
?
boost::shared_ptr<>
提供一定程度的線程安全性。 引用計數以線程安全方式進行操作(除非您將boost配置為禁用線程支持)。
因此,您可以復制shared_ptr
並正確維護ref_count。 你不能在多個線程中安全地做的是從多個線程修改實際的shared_ptr
對象實例本身(例如從多個線程調用reset()
)。 因此,您的使用不安全 - 您正在修改多個線程中的實際shared_ptr
實例 - 您需要擁有自己的保護。
在我的代碼中, shared_ptr
通常是按值傳遞的本地或參數,因此沒有問題。 從一個線程到另一個線程我通常使用線程安全隊列。
當然,這些都不能解決訪問shared_ptr
指向的對象的線程安全問題 - 這也取決於您。
好吧,tr1 :: shared_ptr(基於boost)文檔講述了一個不同的故事,這意味着資源管理是線程安全的,而資源管理則不是。
” ...
線程安全
C ++ 0x-only功能包括:rvalue-ref / move支持,分配器支持,別名構造函數,make_shared和allocate_shared。 此外,采用auto_ptr參數的構造函數在C ++ 0x模式下已棄用。
Boost shared_ptr文檔的Thread Safety部分說“shared_ptr對象提供與內置類型相同的線程安全級別。” 實現必須確保對單獨的shared_ptr實例的並發更新是正確的,即使這些實例共享引用計數,例如
shared_ptr a(新A); shared_ptr b(a);
//線程1 //線程2
a.reset(); b.reset();
動態分配的對象必須由其中一個線程銷毀。 弱引用使事情變得更有趣。 用於實現shared_ptr的共享狀態必須對用戶透明,並且必須始終保留不變量。 共享狀態的關鍵部分是強弱參考計數。 對這些線程的更新需要是原子的並且對所有線程都是可見的,以確保正確清理托管資源(畢竟,這是shared_ptr的工作!)在多處理器系統上,可能需要內存同步,以便引用計數更新和銷毀托管資源是無競爭的。
......”
見http://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.shared_ptr
m_Res不是線程安全的,因為它同時讀/寫,你需要boost :: atomic_store / load函數來保護它。
//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write
添加,您的類具有循環引用條件; shared_ptr<CResource> m_Res
不能是CResourceBase
的成員。 您可以改用weak_ptr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.