互斥体是否锁定自身,或有问题的内存位置?
Does a mutex lock itself, or the memory positions in question?
假设我们有一个全局变量和一个全局非成员函数。
int GlobalVariable = 0;
void GlobalFunction();
我们有
std::mutex MutexObject;
然后在其中一个线程中,我们有这段代码:
{
std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
现在,在并行的另一个线程中 运行,如果我们这样做会发生什么:
{
//std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
所以问题是,当被另一个线程拥有时,互斥体是否只锁定自己不被拥有,而不关心关键代码中试图访问的内容?还是编译器,或者在 运行 时间,OS 实际上将关键代码中正在访问的内存位置指定为暂时被 MutexObject 阻止?
我的猜测是前者,但我需要听取经验丰富的程序员的意见;感谢您花时间阅读我的问题。
是前者。互斥锁和你用互斥锁保护的对象之间没有关系。 (通常,编译器不可能准确地推断出给定代码块将修改哪些对象。)互斥量背后的魔力完全来自于它所做的时间顺序保证:线程在释放互斥量之前所做的一切都是可见的获取互斥量后转到下一个线程。但是这两个线程都需要主动使用互斥锁才能实现。
真正关心线程访问和修改了哪些内存位置并安全地构建在其之上的系统是“事务内存”。它没有被广泛使用。
假设我们有一个全局变量和一个全局非成员函数。
int GlobalVariable = 0;
void GlobalFunction();
我们有
std::mutex MutexObject;
然后在其中一个线程中,我们有这段代码:
{
std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
现在,在并行的另一个线程中 运行,如果我们这样做会发生什么:
{
//std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
所以问题是,当被另一个线程拥有时,互斥体是否只锁定自己不被拥有,而不关心关键代码中试图访问的内容?还是编译器,或者在 运行 时间,OS 实际上将关键代码中正在访问的内存位置指定为暂时被 MutexObject 阻止?
我的猜测是前者,但我需要听取经验丰富的程序员的意见;感谢您花时间阅读我的问题。
是前者。互斥锁和你用互斥锁保护的对象之间没有关系。 (通常,编译器不可能准确地推断出给定代码块将修改哪些对象。)互斥量背后的魔力完全来自于它所做的时间顺序保证:线程在释放互斥量之前所做的一切都是可见的获取互斥量后转到下一个线程。但是这两个线程都需要主动使用互斥锁才能实现。
真正关心线程访问和修改了哪些内存位置并安全地构建在其之上的系统是“事务内存”。它没有被广泛使用。