boost::unordered::concurrent_node_map 使用指南
Boost 的 concurrent_node_map 是一个线程安全的哈希表,支持高并发操作。以下是使用指南及示例:
基本用法
1. 头文件与命名空间
#include <boost/unordered/concurrent_node_map.hpp>
using namespace boost::unordered;
2. 创建实例
concurrent_node_map<int, std::string> map;
3. 插入元素
// 插入键值对
map.insert({1, "one"});
map.emplace(2, "two");
// 使用 try_emplace(键存在则不插入)
bool inserted = map.try_emplace(3, "three");
4. 访问元素
// 使用 visit 访问元素(原子操作)
map.visit(1, [](auto& val) {
std::cout << val.second << "\n"; // 输出 "one"
});
// 也可以使用显示的遍历对象
map.visit(1, [](std::pair<const int, std::string>& val) {
std::cout << val.second << "\n"; // 输出 "one"
});
// 注意:对象的key需要使用const修饰
// 检查键是否存在
if (map.contains(2)) {
std::cout << "Key 2 exists.\n";
}
5. 删除元素
size_t erased = map.erase(1); // 返回删除的数量
6. 并发遍历
// 遍历所有元素(线程安全)
map.visit_all([](auto& pair) {
std::cout << pair.first << ": " << pair.second << "\n";
});
多线程示例
#include <boost/unordered/concurrent_node_map.hpp>
#include <thread>
#include <vector>
using namespace boost::unordered;
void insert_work(concurrent_node_map<int, int>& map, int start) {
for (int i = start; i < start + 1000; ++i) {
map.insert({i, i * 10});
}
}
void read_work(concurrent_node_map<int, int>& map, int key) {
map.visit(key, [](auto& val) {
std::cout << "Key " << val.first << " = " << val.second << "\n";
});
}
int main() {
concurrent_node_map<int, int> map;
// 启动多个线程插入数据
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back(insert_work, std::ref(map), i * 1000);
}
// 启动读取线程
std::thread reader([&map] {
for (int i = 0; i < 10000; ++i) {
read_work(map, i);
}
});
// 等待所有线程完成
for (auto& t : threads) t.join();
reader.join();
return 0;
}
关键特性
-
线程安全:
- 所有操作(插入、删除、访问)可并发执行,无需外部锁。
- 内部通过细粒度锁或无锁技术实现并发。
-
原子操作:
visit/cvisit保证在访问期间元素状态不变。try_emplace等操作保证原子性。
-
高性能设计:
- 开放寻址法减少内存开销。
- 批量操作(如
visit_all)优化遍历效率。
注意事项
- 哈希函数与比较器:需确保线程安全,默认使用
boost::hash和std::equal_to。 - 内存分配器:推荐使用线程安全的分配器(如默认的
std::allocator)。 - 异常安全:大多数操作提供强异常保证。
高级操作
1. 合并哈希表
concurrent_node_map<int, std::string> other_map;
other_map.insert({4, "four"});
map.merge(other_map); // 合并 other_map 到 map
2. 条件删除
// 删除值为偶数的键
map.erase_if([](auto& pair) {
return pair.second % 2 == 0;
});
3. 提取节点
auto node = map.extract(2); // 提取键为 2 的节点
if (!node.empty()) {
// 修改节点值
node.mapped() = "new two";
map.insert(std::move(node)); // 重新插入
}
通过上述示例和说明,可以安全地在多线程环境中使用 concurrent_node_map 实现高效的数据存取。

浙公网安备 33010602011771号