我们在这里:
template<typename TK, typename TV>
class MetaAssociator
{
public:
void Set(TK key, TV const & value)
{
boost::lock_guard<boost::mutex> lock(m_Mutex);
m_Map[key] = value;
}
TV Get(TK key) const
{
boost::lock_guard<boost::mutex> lock(m_Mutex); // this one
std::map<TK,TV>::const_iterator iter = m_Map.find(key);
return iter == m_Map.end() ? TV() : iter->second;
}
private:
mutable boost::mutex m_Mutex;
std::map<TK,TV> m_Map;
};
我们真的需要在get函数中锁定互斥锁吗?我们只提供只读访问权限。如果我们不怎么办?
答案 0 :(得分:5)
是的,我们需要它。
假设有2个线程A和B:
此处可以生成数据争用条件,包括分段错误(线程B正在尝试使用不再存在的对象)。
我们可以使用互斥锁来保护这些部分(如您的示例中所示)。另一种选择是使用read and write lock。读写锁的优点是允许并发读访问。
答案 1 :(得分:3)
是。在并行编程101中,您了解到您的流程可以随时中断,包括您在iter=
函数中选择了Get
。如果另一个进程在第一个进程正在休眠时执行带有Set
函数的插入,则iter
变量会损坏,因为它现在正在引用可能已移动的元素(由于任何原因)
答案 2 :(得分:3)
从两个执行线程同时访问同一个对象,至少在访问是一个修改时,是未定义行为的典型示例,在这种情况下是数据竞争。
正因为如此,除非你有其他方法可以保证Set
永远不会与Red
同时调用(虽然同步放在程序的其他部分),你需要一个同步原语。但是,正如其他评论员所说,std::shared_mutex
可能更适合读/写类型的锁。
答案 3 :(得分:2)
问题是双重的。
答案 4 :(得分:1)
因为某个过程可以在另一个过程正在阅读时写入。
检查经典的“读者作家问题”