我有一个std::map
将从多个线程修改,我有一个互斥锁来锁定这些写入。但是,在长时间运行的操作中偶尔必须使用映射,并且在整个操作期间保持锁定并阻止所有这些写入是不合适的。
我有两个问题:
例如:
class Foo {
void writeToMap(Bar &bar, Baz &baz) {
// lock mutex
map[bar] = baz;
// unlock mutex
}
std::map<Bar, Baz> getMapCopy() {
// lock mutex (Is this necessary?)
std::map<Bar, Baz> copy (map);
// unlock mutex
return copy;
}
std::map<Bar, Baz> map;
};
void expensiveOperation(Foo &f) {
std::map<Bar, Baz> mapCopy = f.getMapCopy();
// Can I safely read mapCopy?
}
答案 0 :(得分:3)
听起来复制操作本身不是线程安全的,问题是复制64位值的原子性。您复制前4个字节,而第二个4由另一个线程修改,留下8个字节不一致。
请在这里查看:Is copy thread-safe?
但是,如果您设法创建一致的副本,我不明白为什么不...
答案 1 :(得分:2)
在该代码中有undefined behavior,因为您返回对局部变量的引用。一旦函数返回,这个locla变量将被破坏,你现在可以引用一个被破坏的对象。
如果您想要返回副本,那么您必须按值返回,这样就好了。
std::map<Bar, Baz> getMapCopy() {
return map;
}
如果你使用C++11 standard thread library中的互斥锁和锁定,你不需要显式解锁,那么互斥锁将在解锁时解锁。