我们需要在 std::map<K, V>::find 函数周围锁定互斥量吗?
Do we need to lock mutex around std::map<K, V>::find function?
我们在这里:
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 函数中锁定 mutex 吗?我们仅提供只读访问权限。如果我们不这样做呢?
因为一些进程可以在另一个正在读的时候写。
查经典"Readers Writers Problem"
从两个执行线程同时访问同一个对象,当至少 on access 是一个修改时,是未定义行为的典型示例,在本例中是数据竞争。
因此,除非你有其他方法来保证 Set
永远不会与 Red
同时调用(尽管同步放在程序的其他部分)你确实需要一个同步原语那里。但是,正如其他评论员所建议的那样,std::shared_mutex
可能更适合 read/write 类型的锁。
是的,我们需要它。
假设有 2 个线程 A 和 B:
- 线程A正在设置值。
- 线程B正在同时读取这个值。
这里可以产生数据竞争条件,包括分段错误(线程 B 正在尝试使用不再存在的对象)。
我们可以使用互斥锁来保护这些部分(就像在您的示例中一样)。另一种选择是使用 read and write lock。 read-write 锁的优点是允许并发 read-access.
问题是two-fold。
- 自我锁定:是的,由于潜在的重新排序、部分 read/writes 和其他类似的事情,它是必需的
- 数据安全:您通过 Get() 获得了一个结果,然后从映射中删除了该条目(与 getter 和 setter 的保护方式相同),然后尝试访问存储的结果本地。那应该怎么办?例如,如果电视只是指向某物的原始指针,那么您手中的死 link 就会遇到麻烦...
我们在这里:
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 函数中锁定 mutex 吗?我们仅提供只读访问权限。如果我们不这样做呢?
因为一些进程可以在另一个正在读的时候写。
查经典"Readers Writers Problem"
从两个执行线程同时访问同一个对象,当至少 on access 是一个修改时,是未定义行为的典型示例,在本例中是数据竞争。
因此,除非你有其他方法来保证 Set
永远不会与 Red
同时调用(尽管同步放在程序的其他部分)你确实需要一个同步原语那里。但是,正如其他评论员所建议的那样,std::shared_mutex
可能更适合 read/write 类型的锁。
是的,我们需要它。
假设有 2 个线程 A 和 B:
- 线程A正在设置值。
- 线程B正在同时读取这个值。
这里可以产生数据竞争条件,包括分段错误(线程 B 正在尝试使用不再存在的对象)。
我们可以使用互斥锁来保护这些部分(就像在您的示例中一样)。另一种选择是使用 read and write lock。 read-write 锁的优点是允许并发 read-access.
问题是two-fold。
- 自我锁定:是的,由于潜在的重新排序、部分 read/writes 和其他类似的事情,它是必需的
- 数据安全:您通过 Get() 获得了一个结果,然后从映射中删除了该条目(与 getter 和 setter 的保护方式相同),然后尝试访问存储的结果本地。那应该怎么办?例如,如果电视只是指向某物的原始指针,那么您手中的死 link 就会遇到麻烦...