簡體   English   中英

如何以線程安全的方式使用`std::unordered_map`?

[英]How to use `std::unordered_map` in a thread-safe way?

我做了什么

我的想法是包裝std::unordered_map ,並為每個操作鎖定它。 它看起來像這樣(我將只留下一個操作,以免混淆問題):

template<class Key, class T>
class thread_safe_unordered_map {
   public:
    T &operator[](const Key &key) {
        std::lock_guard<std::mutex> lock{m_mutex};
        return m_underlying[key];
    }

   private:
    std::unordered_map<Key, T> m_underlying;
    std::mutex                 m_mutex;
};

但是后來我想到了這一點,現在我不知道如何正確地做到這一點。

想象一下這種情況。

線程1:調用operator[]寫
線程 2:調用 operator[] 從中讀取

兩者都做自己的事情。 現在,因為 operator[] 返回一個引用,並且它們都將作用於同一個引用,我認為這仍然可能是數據競爭。 這是正確的嗎?

我現在的想法

因為這個

所有 const 成員函數都可以被同一容器上的不同線程並發調用。 另外,成員函數begin()、end()、rbegin()、rend()、front()、back()、data()、find()、lower_bound()、upper_bound()、equal_range()、 at(),並且,除了在關聯容器中,operator[] 出於線程安全的目的表現為 const。

我有這個問題。 在線程上使用at()是否正確,並且被鎖定的是映射值?

現在,因為 operator[] 返回一個引用,並且它們都將作用於同一個引用,我認為這仍然可能是數據競爭。 這是正確的嗎?

假設T不是線程安全類型,這是正確的。

這不是容器操作中的數據競爭,而是使用類型T的對象中的數據競爭。

我有這個問題。 在線程上使用 at() 是否正確

如果您只調用限定at的常量,那么您永遠不會獲得非常量引用,因此無法修改任何元素的值。 如果您不修改這些值,則不會發生數據競爭。

如果您使用限定at ,則在描述的數據競爭方面沒有區別。

PS 你會發現你不能有任何同步的非常量成員函數,因為鎖定互斥體需要修改。 你可以使用mutable來解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM