如果您不需要unordered_map的所有功能,则此解决方案应适用于您。 它使用互斥锁来控制对内部unordered_map的访问。 此解决方案支持以下方法,添加更多方法应该相当容易:
- getOrDefault(key, defaultValue) - 返回与key相关联的值,如果不存在关联,则返回defaultValue。 当不存在关联时,不会创建映射条目。
- contains(key) - 返回布尔值; 如果存在关联则为true。
- put(key, value) - 创建或替换关联。
- remove(key) - 删除与key相关联的关联
- associations() - 返回包含当前已知所有关联的向量。
示例用法:
#include <iostream>
#include "SynchronizedMap.h"
using namespace std;
using namespace Synchronized;
int main(int argc, char **argv) {
SynchronizedMap<int, string> activeAssociations;
activeAssociations.put({101, "red"});
activeAssociations.put({102, "blue"});
activeAssociations.put({102, "green"});
activeAssociations.put({104, "purple"});
activeAssociations.put({105, "yellow"});
activeAssociations.remove(104);
cout << ".getOrDefault(102)=" << activeAssociations.getOrDefault(102, "unknown") << "\n";
cout << ".getOrDefault(112)=" << activeAssociations.getOrDefault(112, "unknown") << "\n";
if (!activeAssociations.contains(104)) {
cout << 123 << " does not exist\n";
}
if (activeAssociations.contains(101)) {
cout << 101 << " exists\n";
}
cout << "--- associations: --\n";
for (auto e: activeAssociations.associations()) {
cout << e.first << "=" << e.second << "\n";
}
}
示例输出:
.getOrDefault(102)=green
.getOrDefault(112)=unknown
123 does not exist
101 exists
--- associations: --
105=yellow
102=green
101=red
注意1:associations()方法不适用于非常大的数据集,因为在创建向量列表期间它会锁定表格。
注意2:我故意没有扩展unordered_map,以防止自己意外使用未扩展的unordered_map方法,因此可能不是线程安全的。
#pragma once
#include <unordered_map>
#include <mutex>
#include <vector>
#ifndef __SynchronizedMap__
#define __SynchronizedMap__
using namespace std;
namespace Synchronized {
template <typename KeyType, typename ValueType>
class SynchronizedMap {
private:
mutex sync;
unordered_map<KeyType, ValueType> usermap;
public:
ValueType getOrDefault(KeyType key, ValueType defaultValue) {
sync.lock();
ValueType rs;
auto value=usermap.find(key);
if (value == usermap.end()) {
rs = defaultValue;
} else {
rs = value->second;
}
sync.unlock();
return rs;
}
bool contains(KeyType key) {
sync.lock();
bool exists = (usermap.find(key) != usermap.end());
sync.unlock();
return exists;
}
void put(pair<KeyType, ValueType> nodePair) {
sync.lock();
if (usermap.find(nodePair.first) != usermap.end()) {
usermap.erase(nodePair.first);
}
usermap.insert(nodePair);
sync.unlock();
}
void remove(KeyType key) {
sync.lock();
if (usermap.find(key) != usermap.end()) {
usermap.erase(key);
}
sync.unlock();
}
vector<pair<KeyType, ValueType>> associations() {
sync.lock();
vector<pair<KeyType, ValueType>> elements;
for (auto it=usermap.begin(); it != usermap.end(); ++it) {
pair<KeyType, ValueType> element (it->first, it->second);
elements.push_back( element );
}
sync.unlock();
return elements;
}
};
}
#endif
concurrent_hash_map
,我已经使用过它并且效果很好。请参考完整示例代码。 - Contango