我有一个std::map<std::string, std::tuple<int, int, std::atomic<int>>> mp
。这个Map可以并行读写,所以我使用了一个读写锁来保证它的线程安全。
我想知道我是否可以在读锁区域写入std::get<2>(mp["someKey"])
。
void read() {
// read lock area
std::shared_lock<std::shared_mutex> read_lock{mtx};
// "someKey" exists already
std::get<2>(mp["someKey"]).store(2);
}
字符串
我试着做了一些测试,似乎它的工作,但我不知道它是否是不正确的,并给我一个核心转储的一天。
1条答案
按热度按时间o0lyfsai1#
首先,请注意
mp["someKey"]
修改了Map,并且不是线程安全的。如果还不存在键,operator[]
将创建一个新的值初始化的键/值对。参见Why is std::map::operator[] considered bad practice?相反,您应该使用
mp.at("someKey")
或mp.find("someKey")
:字符串
.store(2);
是线程安全的,因为从多个线程同时写入std::atomic
是安全的。std::shared_lock
不是确保这一点的必要条件。但是,std::shared_lock
确保周围的std::pair
不会被另一个线程破坏,因此必须保留。const-correctness注意事项
Const-correctness可以防止
mp["someKey"]
的错误。如果您只持有读锁,那么使用const&
来防止意外修改是一个很好的做法:型
std::tuple
注意事项变量模板之外的
std::tuple
总是有问题的。有意义的名字总是更好:型