[英]Is shared_ptr destruction safe with multiple threads?
我有兩個類似的類:
class Foo {
public:
void bar() {
std::lock_guard<std::mutex> lock(m_mutex);
m_data.push_back('x');
}
private:
std::string m_data;
std::mutex m_mutex;
};
class Pool {
public:
static std::shared_ptr<Foo> Create(int index) {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_pool.size() > 10) {
m_pool.erase(m_pool.begin());
}
std::shared_ptr<Foo>& ptr = m_pool[index];
if (!ptr) ptr.reset(new Foo);
return ptr;
}
private:
static std::mutex m_mutex;
static std::map<int, std::shared_ptr<Foo>> m_pool;
};
以及運行此代碼的幾個線程:
void parallel_function(int index) {
// several threads can get the same index
std::shared_ptr<Foo> foo = Pool::Create(index);
foo->bar();
}
所有成員函數(包括復制構造函數和復制賦值)都可以由shared_ptr的不同實例上的多個線程調用,而無需額外的同步,即使這些實例是副本並共享同一對象的所有權。 如果多個執行線程在沒有同步的情況下訪問相同的shared_ptr,並且這些訪問中的任何一個使用shared_ptr的非const成員函數,那么將發生數據爭用; 原子函數的shared_ptr重載可用於防止數據競爭。
兩個問題:
由於Pool::Create
總是返回shared_ptr
的副本,我假設每個shared_ptr
的復制和銷毀都是線程安全的,如果它發生在m_pool.erase
或者在parallel_function
的末尾。 它是否正確?
我調用shared_ptr::operator->
,這是一個const成員函數,函數Foo::bar
是線程安全的。 這里有數據競爭嗎?
總結一下我的評論。
shared_ptr
的單獨副本。 這是少數幾個傳遞shared_ptr
副本實際上是合理的情況之一。 operator->
是一個const成員 。 所以基本上你的代碼很好,只要Foo :: bar無競賽就是真的(現在很明顯)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.