【问题标题】:Could unordered_map find and insert at the same time? [duplicate]unordered_map 可以同时查找和插入吗? [复制]
【发布时间】:2019-03-16 06:58:38
【问题描述】:

我是 C++ 多线程编程的新手。我从网上阅读了一些文档和一些文章,并注意到在 STL unordered_map 中允许同时进行多次查找操作,而不允许进行多次插入操作。

我有两个问题:

  1. 可以同时进行查找操作和插入操作吗?例如,

    std::string x = "jim";
    std::string y = "marry";
    std::unordered_map<std::string, int> map;  
    // Thead A executes below code 
    auto iterator = map.find(x);   
    // Thread B executes below code
    map.insert(std::make_pair(y, "value"));
    

    请注意这里的 x 和 y 不相同。

  2. 如果 x 和 y 相同怎么办?如果我们找到密钥并同时插入相同的密钥会发生什么?

谢谢各位,如果您回答这个问题,请参考您获得这些知识的参考资料。

【问题讨论】:

  • linkLalaland 的回答实际上解决了我的问题。但是在我提出这个问题之前,由于没有参考,我无法从他的回答中确定规则的正确性。 @kmdredo 提供了参考,消除了我的疑虑。感谢关注这个问题的人:)

标签: c++ multithreading stl unordered-map


【解决方案1】:

两者的答案: 由于 C++ 内存模型的规则,这样的数据竞争会导致未定义的行为。所以任何事情都有可能发生。您必须保证安全操作,并应添加 std::mutex 例如(https://en.cppreference.com/w/cpp/thread/mutex)

【讨论】:

    【解决方案2】:

    标准容器不是线程安全的。因此,您需要将 unordered_map 包装到类中并公开线程安全函数以插入和查找项目,例如使用互斥锁。

    这是一些伪代码:

    class my_map
    {
    private:
        static std::mutex my_mutex;
        typedef map<std::string, int> my_map;
        std::unordered_map my_map;
    public:
        void insert(...)
        {
            my_mutex.lock();
            map.insert(...);
            my_mutex.unlock(); // still not safe in case of exception
        }
        my_map::iterator find(...)
        {
            my_mutex.lock();
            var result = map.find(...);
            my_mutex.unlock();
            return result;
        }
    }
    

    【讨论】:

    • std::lock_guard&lt;std::mutex&gt; 对于异常安全互斥锁使用非常有用
    • 没错,std::lock_guard 避免使用 try __finally
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2013-04-13
    • 1970-01-01
    相关资源
    最近更新 更多