线程安全的unordered_map

std::unordered_map 是 C++ 标准库中的哈希表实现的关联数组,它本身不是线程安全的,多个线程同时访问和修改同一个 unordered_map 可能会导致数据竞争和未定义行为。
使用 C++11 标准库中的 std::shared_mutex 实现读写锁来保护 std::unordered_map,允许多个线程同时读取 unordered_map,但只允许一个线程写入 unordered_map,可以提高并发性能。

#include <unordered_map>
#include <shared_mutex>
#include <iostream>
#include <mutex>
#include <map>
#include <functional>

template<typename Key, typename Value>
class safeUnorderedMap {
public:
    safeUnorderedMap() {}

    void insert(const Key& key, const Value& value) {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        map_[key] = value;
    }

    void erase(const Key& key) {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        map_.erase(key);
    }

    bool find(const Key& key, Value& value) const {
        std::shared_lock<std::shared_mutex> lock(mutex_);
        auto it = map_.find(key);
        if (it == map_.end()) {
            return false;
        }
        value = it->second;
        return true;
    }
    
    void clear() {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        map_.clear();
    }
    
    size_t size() const {
        std::lock_guard<std::shared_mutex> lock(mutex_);
        return map_.size();
    }

    std::map<Key, Value> getMap() const {
        std::lock_guard<std::shared_mutex> lock(mutex_);
        return map_;
    }

    void forEach(std::function<void(const Key&, const Value&)> f) const {
        std::shared_lock<std::shared_mutex> lock(mutex_);
        for (const auto& kv : map_) {
            f(kv.first, kv.second);
        }
    }

private:
    mutable std::shared_mutex mutex_;
    std::unordered_map<Key, Value> map_;
};

template<typename Key, typename Value>
class safeMap : public safeUnorderedMap<Key, Value>
{
private:
    mutable std::shared_mutex mutex_;
    std::map<Key, Value> map_;
};

int main()
{
   safeMap<int, int> myMap;

    // 插入元素
    myMap.insert(1, 10);
    myMap.insert(2, 20);
    myMap.insert(3, 30);

    // 查找元素
    int value;
    if (myMap.find(2, value)) {
        std::cout << "value of key 2: " << value << std::endl;
    } else {
        std::cout << "key 2 not found" << std::endl;
    }

    // 删除元素
    myMap.erase(3);

    // 清空容器
    myMap.clear();

    // 遍历容器
    myMap.insert(4, 40);
    myMap.insert(5, 50);
    myMap.forEach([](const int& key, const int& value) {
        std::cout << key << ": " << value << std::endl;
    });  
    
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++11 引入了一些线程安全的容器,其中包括了 `std::unordered_map` 的线程安全版本 `std::unordered_map`。这些线程安全容器在内部实现了并发控制,以确保在多线程环境下的安全访问。 `std::unordered_map` 的线程安全版本 `std::unordered_map` 在并发访问控制上进行了以下改进和更新: 1. 线程安全:`std::unordered_map` 在内部使用了互斥锁(`std::mutex`)或其他并发控制机制来实现线程安全。这样,在多个线程同时对 `std::unordered_map` 进行操作时,会自动进行并发控制,保证数据的一致性和线程安全性。 2. 锁粒度:`std::unordered_map` 的线程安全版本通常会使用细粒度锁(fine-grained locking)的方式,即将哈希表中的每个桶(bucket)都配备一个互斥锁。这样,在进行插入、删除或查询操作时,只需要锁定对应的桶,并发度更高,减少了锁竞争的概率,提高了并发性能。 3. 迭代器安全:`std::unordered_map` 在线程安全版本中,迭代器的操作是线程安全的,可以在多个线程中同时使用迭代器进行遍历或访问,而不需要额外的同步机制。 需要注意的是,虽然 `std::unordered_map` 的线程安全版本提供了一定程度的并发控制,但在特定场景下仍可能需要额外的同步机制来实现更细粒度的并发控制或满足特定的业务需求。因此,在使用 `std::unordered_map` 的线程安全版本时,仍需要谨慎设计并发访问策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值