它是安全锁/范围保护实现
Is it safe lock/scope guard implementation?
现在我从类中获取线程安全字段的实现:
int A::GetValue() const
{
_mutex.Lock();
int temp = _value;
_mutex.Unlock();
return temp;
}
我想用这样的锁/作用域保护实现来代替它(LockGuard类只有构造函数/析构函数和Mutex * _mutex字段):
LockGuard::LockGuard(Mutex & mutex) : _mutex(&mutex)
{
_mutex->Lock();
}
LockGuard::~LockGuard()
{
_mutex->Unlock();
}
和重构代码:
int A::GetValue() const
{
LockGuard lockGuard(_mutex);
return _value;
}
我突然意识到,我不确定这是否是一个安全的实现。它是否保证首先_value的副本将被传递出函数,并且只有当这个副本已经存在时,_互斥锁才会被解锁?请不要提供c++ 11的替代实现示例-我有嵌入式系统,不幸的是不能使用它们。
这一行有问题:
LockGuard(_mutex);
应该是:
LockGuard foo(_mutex);
否则,它将超出作用域并在方法的其余部分执行之前解锁互斥锁。(您可以通过在LockGuard构造函数和析构函数以及调用方法中临时插入printf或类似的方法来验证有问题的行为)。
除此之外,你的锁模式是好的
也许这个程序可以帮助你想象发生了什么:
#include <iostream>
// Replaces the int so that we know when things happen
struct Int {
Int() {
std::cout << "Int::Int()" << std::endl;
}
~Int() {
std::cout << "Int::~Int()" << std::endl;
}
Int(const Int &x) {
std::cout << "Int::Int(const Int&)" << std::endl;
}
};
struct LockGuard {
LockGuard() {
std::cout << "Locking" << std::endl;
}
~LockGuard() {
std::cout << "Unlocking" << std::endl;
}
};
struct A {
Int getValue() const {
LockGuard lockGuard;
return _value;
}
Int _value;
};
int main() {
A a;
std::cout << "about to call" << std::endl;
Int x=a.getValue();
std::cout << "done calling" << std::endl;
}
结果是
Int::Int()
about to call
Locking
Int::Int(const Int&)
Unlocking
done calling
Int::~Int()
Int::~Int()
最后需要注意的是,您可能需要在属性声明中使用_mutex
mutable
,因为锁定和解锁通常是非const操作,否则在const方法中是不允许的
你的LockGuard
的实现是好的,但使用是错误的。使用语句
LockGuard(_mutex);
您正在创建一个临时的LockGuard
,它将在语句完成后被销毁。
用法应该是
LockGuard guard(_mutex);
return _value;
LockGuard guard(_mutex);
将创建一个LockGuard
对象,该对象将锁定构造函数中的互斥锁。当方法返回时,将调用析构函数,解锁互斥锁。并且您不再需要使用临时返回
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 使用std::transform将一个范围的元素添加到另一个范围中
- 为什么在保护模式下继承升级不起作用
- 在基于范围的for循环中使用结构化绑定声明
- 访问被拒绝后,c++中的故障保护代码
- C++:无法访问声明的受保护成员
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 为什么您需要C++头文件的包含保护
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 离开范围后如何保护局部变量的值?
- 在受保护的范围内切换C++ xcode
- 基于范围的锁保护和返回值的计时
- 它是安全锁/范围保护实现