多线程操作std::map:同时读写是否存在未定义行为?
多线程操作std::map的未定义行为问题
会出现未定义行为,原因如下:
- C++标准明确规定,非线程安全容器(如
std::map)在无同步机制的前提下,同时进行写操作与读操作会触发数据竞争,而数据竞争属于未定义行为范畴。 - 你的代码中,线程1执行的
my_map[9] = 9属于写操作(若键9不存在则插入新元素,存在则修改对应值);线程2的check_and_act函数里调用my_map.find(9)属于读操作。两个线程没有任何同步措施,只要两类操作在时间上存在重叠(哪怕是极短的瞬间),就会触发数据竞争,进而导致程序崩溃、返回错误结果或出现其他不可预测的表现。
哪怕你不在意线程1与线程2的执行顺序,只要没有同步机制,就无法规避这种风险。
解决方法
给std::map的所有访问(读、写操作)添加同步锁,比如使用std::mutex:
#include <mutex> #include <map> std::map<int, int> my_map; std::mutex map_mutex; // 线程1代码 void thread1_func() { std::lock_guard<std::mutex> lock(map_mutex); my_map[9] = 9; } // 线程2代码 void check_and_act() { std::lock_guard<std::mutex> lock(map_mutex); if(my_map.find(9) == my_map.end()) { // do something } }
std::lock_guard会自动管理锁的生命周期,避免手动加锁解锁时出现遗漏或异常导致的锁泄漏问题。
内容的提问来源于stack exchange,提问作者tesla1060
相关产品推荐
相关产品推荐

