我需要以CAS方式更新由TBB提供的concurrent_hash_map中的內容。也就是說,如果一個鍵已經存在,我查看與該鍵相對應的值並在原子操作中更新該值(如果由於另一個線程做同樣的事情而導致該值同時發生變化,那麼我的操作將失敗)。tbb併發哈希映射:如何比較和設置
換句話說,我爲插入方法提供了一個「預期值」,並且只有在當前值與期望值匹配時才更新值。
TBB的concurrent_hash_map中有一個實現這個嗎?
非常感謝。
我需要以CAS方式更新由TBB提供的concurrent_hash_map中的內容。也就是說,如果一個鍵已經存在,我查看與該鍵相對應的值並在原子操作中更新該值(如果由於另一個線程做同樣的事情而導致該值同時發生變化,那麼我的操作將失敗)。tbb併發哈希映射:如何比較和設置
換句話說,我爲插入方法提供了一個「預期值」,並且只有在當前值與期望值匹配時才更新值。
TBB的concurrent_hash_map中有一個實現這個嗎?
非常感謝。
給定類型Key和T,下面的代碼實現了目標,假設類型T是支持tbb :: atomic的類型。
class AtomicValue {
mutable tbb::atomic<T> content;
public:
AtomicValue() {}
AtomicValue(T value) {content=value;}
bool cas(T value, T comparand) const {
return content.compare_and_swap(value,comparand)==comparand;
}
};
typedef tbb::concurrent_hash_map<Key,AtomicValue> table;
bool update(table& x, Key key, T value, T comparand) {
table::const_accessor a;
if(!x.insert(a,table::value_type(key,value))) {
// value is already there
return a->second.cas(value,comparand);
}
return true;
}
棘手的部分是使用const_accessor進行更新。使用常規訪問器將序列化更新。但是const_accessor允許多個線程同時訪問同一個表項。它被稱爲「const_accessor」,因爲通常的用例涉及讀取值。但是這裏的代碼使用CAS來仲裁更新。包裝類「AtomicValue」可以在一個const對象上執行CAS。
一個類似的解決方案應該適用於tbb :: concurrent_unordered_map,這可能會更好,如果非阻塞是關鍵標準,因爲concurrent_unordered_map有一個非阻塞實現。
更重要的是,如果您有最新的TBB 和支持constexpr的C++ 11的特性和違約/刪除成員函數,下面應該工作編譯器:
typedef tbb::concurrent_unordered_map<Key,tbb::atomic<T> > table;
bool update(table& x, Key key, T value, T comparand) {
auto p = x.insert(table::value_type(key,value));
if(!p.second) {
// value is already there
return p.first->second.compare_and_swap(value,comparand) == comparand;
}
return true;
}
它工作了我用gcc 4.7編譯時使用「g ++ -std = C++ 0x」。
這就是我一直在尋找的。非常感謝。 – 2013-03-06 02:24:10