我有一個容器(C++),我需要以兩種方式從不同的線程操作:1)添加和移除元素,2)遍歷其成員。顯然,迭代發生時刪除元素=災難。該代碼看起來是這樣的:如何以線程安全的方式迭代容器?
class A
{
public:
...
void AddItem(const T& item, int index) { /*Put item into my_stuff at index*/ }
void RemoveItem(const T& item) { /*Take item out of m_stuff*/ }
const list<T>& MyStuff() { return my_stuff; } //*Hate* this, but see class C
private:
Mutex mutex; //Goes in the *Item methods, but is largely worthless in MyStuff()
list<T> my_stuff; //Just as well a vector or deque
};
extern A a; //defined in the .cpp file
class B
{
...
void SomeFunction() { ... a.RemoveItem(item); }
};
class C
{
...
void IterateOverStuff()
{
const list<T>& my_stuff(a.MyStuff());
for (list<T>::const_iterator it=my_stuff.begin(); it!=my_stuff.end(); ++it)
{
...
}
}
};
再次,B::SomeFunction()
和C::IterateOverStuff()
越來越異步調用。我可以使用什麼數據結構來確保在迭代期間,my_stuff
受到添加或刪除操作的「保護」?
+1。 Boost有這些實現:http://www.boost.org/doc/libs/1_46_1/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.shared_mutex – 2011-04-14 18:08:26
@Evan,@larsmans我沒有很明白 - 我會在哪裏放?只需將其全局定義並放入C :: Iterate ...以及A方法中即可?它如何「知道」是否正在執行讀取或寫入 – 2011-04-14 18:16:47
@Matt:它可能應該與列表本身具有相同的範圍/所有權。如果列表是全局的,那麼鎖應該是全局的。如果某個對象擁有該列表,則該同一對象應該擁有該鎖。 – 2011-04-14 18:20:16