【问题标题】:unordered_map find() and operator []unordered_map find() 和运算符 []
【发布时间】:2016-01-27 14:34:09
【问题描述】:

我有一个全局变量 std::unordered_map themap 。

thread1 执行以下操作:

Time1 : 
string s = "user1" ; 
themap[s] = 100 ;

Time2 :
string s = "user2" ;
themap[s] = 101 ;

thread2 执行以下操作:

Time2:
string s = "user1" ;
auto got = themap.find( s ) ;

Time1 发生在 Time2 之前,假设在 thread2 中 got != themap.end() 将是正确的, got->second = 100 !!!困扰我的是,如果在 Time2 的那一刻,thread1 正在执行 themap["user2"] = 101 ,这将修改 map 的内存结构,thread2 themap.find 在完全相同的时间执行 find,thread1 修改了 map 的内存内容,如果没有锁,我仍然得到 得到 != themap.end() 吗?并且得到->second = 100 ?

themap["user2"] = 101 得到 = themap.find(s)
同时做会导致got->second不是100?

【问题讨论】:

  • 如果这两个线程之间没有同步,那么您就有一个竞争条件并且您的程序表现出未定义的行为。这意味着它可以合法地产生任何结果。

标签: c++ c++11 thread-safety g++ unordered-map


【解决方案1】:

unordered_map thread safe 确实适用于一个线程写入和多个线程读取。

此外,在时间 1 的示例中,您正在修改 "user1" ,然后在时间 2 在线程 2 中进行搜索。您在时间 2 在线程 1 中设置 "user2" 的事实是正交的。

关于正在修改的内存,这不是问题,因为 find 使用的迭代器在您插入新值 will not be invalidated 时启动。

因此在您的测试用例中没有竞争条件。

【讨论】:

    【解决方案2】:

    您可以阻止unorderd_map 更改其内部结构,方法是事先强制它这样做。使用reserve,并将max_load_factor 设置为或接近1.0f

    【讨论】:

    • 谢谢,但地图内容会增加到无法预先确定的数量,谢谢指教!!
    • @barfatchen 欢迎您。您可以在每次插入时检查 load_factor。如果它接近 max_load_factor,请保留例如。 50% 以上,并告诉其他线程。其他解决方案:只使用 std::map 代替,它不会慢很多(只是一点点)。或者,您可以定义自己的哈希函数以满足您的条件。
    猜你喜欢
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多