c++ - 具有互斥锁缓存的类的移动构造函数的最佳实践
问题描述
我有时有这样的课程:
class HasMutexLockedCache {
private:
SomeType m_regularData;
mutable std::mutex m_mutex;
mutable std::optaional<T> m_cache;
// Etc.
public:
const m_regularData& getData() const { return m_regularData; }
const T& getExpensiveResult() const {
std::scoped_lock lock(m_mutex);
if (!m_cache) {
m_cache = expensiveFunction();
}
return m_cache;
}
HasMutexLockedCache(const HasMutexLockedCache& other)
: m_regularData(other.m_regularData)
{
std::scoped_lock lock(other.m_mutex);
// I figure we don't have to lock this->m_mutex because
// we are in the c'tor and so nobody else could possibly
// be messing with m_cache.
m_cache = other.m_cache;
}
HasMutexLockedCache(HasMutexLockedCache&& other)
: m_regularData(std::move(other.m_regularData))
{
// What here?
}
HasMutexLockedCache& operator=(HasMutexLockedCache&& other) {
m_regularData = std::move(other.m_regularData);
// Bonus points: What here? Lock both mutexes? One?
// Only lock this->m_mutex depending on how we
// document thread safety?
}
};
我的问题:什么进入HasMutexLockedCache(HasMutexLockedCache&& other)
(同样在HasMutexLockedCache& operator=(HasMutexLockedCache&& other)
?我认为我们不需要锁定other.m_mutex
,因为other
作为一个右值引用,我们知道没有其他人可以看到它,就像我们不必锁定this->m_mutex
c' tor。但是,我想要一些指导。这里的最佳做法是什么?我们应该锁定other.m_mutex
吗?
解决方案
我想要一些指导。这里有哪些最佳实践?我们应该锁定 other.m_mutex 吗?
@Galik 的回答解释了如何为此实现移动构造函数,但是您应该考虑这对于您的抽象来说是否是一个安全且连贯的想法。
如果一个对象包含 a std::mutex
,通常这意味着它可能在不同的时间有并发访问,这保证了这一点。如果是这种情况,那么在面对多线程时,移动语义可能会非常难以使用——因为您可能让线程 Am_cache
在线程 B 访问它之前移动它的内容,从而导致它读取一个已移动的状态(这取决于正在检查的状态,可能没有明确定义)。这些类型的错误可能很难调试,甚至更难重现!
通常,如果您有这样的类型,最好在线程之间显式共享这种类型,或者通过共享生命周期 via shared_ptr
,或者从外部进行某种形式的同步,这样每个线程就不会破坏性地相互干扰。
推荐阅读
- node.js - Node Js PDF Phantom ENOENT
- azure-devops - Azure Artifacts - 某些用户访问组织范围的源时出现 401 未经授权的错误
- go - 为什么我的所有 goroutine 不执行?需要解释
- azure-active-directory - Microsoft Graph 待办事项 - 无需用户登录 - 可能吗?
- python - 我有一个值列表,我想迭代地将键值对附加到 python 字典
- amazon-web-services - 使用 AWS Athena 分析 DynamoDB 数据
- java - 如何在 Dart 或 Java 中使用给定数组查找范围内的最小缺失数
- android - Kotlin - OnSharedPreferenceChangeListener
- android - 尝试不显示当我单击表单的 EditText 之一时显示的按钮
- node.js - 无法捕获并记录来自 axios 请求的错误