返回对象值时互斥
Mutex when returning object value
如果我了解c++编译器如何处理局部变量,那么IsShutdownInProgress()
不需要任何锁定,因为shutdownInProgress
静态变量将被放置在堆栈上。我说的对吗?
class MyClass
{
private:
// Irrelevant code commented away
static pthread_mutex_t mutex;
static bool shutdownInProgress;
public:
static void ShutdownIsInProgress()
{
pthread_mutex_lock(mutex);
shutdownInProgress = true;
pthread_mutex_unlock(mutex);
}
static bool IsShutdownInProgress()
{
// pthread_mutex_lock(mutex);
// pthread_mutex_unlock(mutex);
return shutdownInProgress;
}
}
我说的对吗?
。这将使它的副本返回;但是在没有同步的情况下读取它来进行复制将产生数据竞争,并具有未定义的行为。您需要在锁住互斥锁的情况下创建一个本地副本:
static bool IsShutdownInProgress()
{
pthread_mutex_lock(mutex);
bool result = shutdownInProgress;
pthread_mutex_unlock(mutex);
return result;
}
或者,使用更不容易出错的RAII锁类型:
static bool IsShutdownInProgress()
{
lock_guard lock(mutex);
return shutdownInProgress;
}
在c++ 11中,您可以考虑std::atomic<bool>
,以便更方便、更有效地从多个线程访问简单类型。
争用条件与变量位于堆上还是堆栈上无关。争用条件是指一个线程正在修改一个变量(内存位置),而另一个线程正在读取或修改同一个变量。不能保证对bool
的修改是原子的,因此发布的代码具有竞争条件,因此行为未定义。
修复方法是存储互斥锁被持有时bool
的值,并返回变量:
static bool IsShutdownInProgress()
{
pthread_mutex_lock(&mutex);
bool result = shutdownInProgress;
pthread_mutex_unlock(&mutex);
return result;
}
c++11引入了可以使用的std::mutex
和std::lock_guard
,使用lock_guard
可以避免使用临时变量来存储用于返回的bool
值:
static std::mutex mtx_;
static bool IsShutdownInProgress()
{
std::lock_guard<std::mutex> lk(mtx_);
return shutdownInProgress;
}
c++11还引入了std::atomic<>
,它将确保修改是原子的,并避免需要显式锁:
static std::atomic<bool> shutdownInProgress;
static bool IsShutdownInProgress()
{
return shutdownInProgress;
}
如果c++11不可用,则boost::atomic
在v1.53.0中引入,boost也有等效的boost::mutex
和boost::lock_guard
是的,它需要一个锁
c++ 11的内存模型指出,如果一个线程在写一个值的同时另一个线程在读这个值,那么你就有一个数据竞争。这是因为读操作和/或写操作可能都不是原子操作。
在这种情况下,你将从函数返回一个局部值,但是要获得该局部值,编译器需要复制shutdownInProgress
中的值,这可能同时被另一个调用ShutdownIsInProgress()
的线程更改。
解决这个问题的一个简单方法是使shutdownInProgress
成为一个原子:
static std::atomic<bool> shutdownInProgress;
如果你让它原子化,你不需要任何锁对于任何函数
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 如何访问从 COM 对象返回的 VARIANT 数据类型中的安全数组C++?
- 从我的对象返回静态数组
- 将unique_ptr作为<Object>unique_ptr<常量对象返回>
- 从右值对象返回成员
- 视觉对象 返回 C++ 中的双精度值
- 为什么类型为 sf::Text 的对象返回不同的 getPosition().y 和 getLocalBounds().
- std::min_element 从类对象返回意外结果
- C++无效的对象返回语义
- const引用是否延长临时对象返回的临时对象的寿命
- 将 NULL 作为对象返回时未收到任何警告
- 如何在 C# 中从 com 对象返回数组(double[])
- 从重载运算符返回引用,并使用临时对象返回表达式
- Cin 对象返回值 c++
- 将变量作为类对象返回
- 使用可更改对象返回只读的最佳方法是什么
- 如何在Cython中从另一个包装对象返回包装的c++对象
- 当对象返回时,c++动态数组被清除
- 从带有动态字段的函数、对象返回
- 从堆栈上的匿名对象返回对*this的引用