当互斥锁/解锁深埋在函数调用中时,我需要栅栏或屏障或其他东西吗?
Do I need a fence or barrier or something when mutex locks/unlocks are buried deep in function calls?
我最近了解到编译器会通过重新排列指令来优化你的代码,这可以通过使用barrier来控制。
在IIRC中,锁定互斥锁会产生一个屏障,解锁互斥锁也会产生一个屏障,以防止临界区内的代码泄露。
所以pthread_mutex_lock和pthread_mutex_unlock必须隐式地成为这些"屏障"。如果我有一个这样的类,它包装了我的互斥锁?
class IMutex {
public:
virtual void lock() = 0;
virtual void unlock() = 0;
};
在我看来,编译器不会知道我在lock()中调用pthread_mutex_lock(),在unlock()中调用pthread_mutex_unlock(),因为它都是虚的。
这会导致bug吗?我是否需要以某种方式手动指定屏障?
指令的重新排序是在不同的级别上完成的。最明显的一个是编译器,不太明显的一个是CPU(它是动态的)。然而,同步函数几乎总是一个栅栏,它防止之前和之后的指令被重新排序。
如果你的虚拟lock
调用pthread_mutex_*()
,那么你的虚拟函数包含一个fence。
所以简短的回答是:不,它不会导致bug。
还有volatile关键字,根据平台的不同,它也可以生成一个fence。但是,使用volatile关键字会使检测这些栅栏变得更加困难,因为每次使用volatile函数或变量时都会引入一个栅栏。因此建议您使用平台的同步功能。
你唯一需要注意的是当你不使用并发对象来执行同步时(比如使用bool
代替互斥锁)。
相关文章:
- 我应该在锁定TBitmap画布后解锁它吗
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- c++ 为什么我不应该从不同的线程解锁互斥锁
- 在新作用域中使用unique_lock是否等效于在使用共享资源的工作结束时解锁调用
- "data race"(不是真的)在通知条件变量并解锁关联的互斥锁后
- 程序输入密码并解锁窗口7,8,10
- 在通知之前完成手动解锁
- STD :: Mutex如何在不同的线程中解锁
- 如何使用单个解锁方法(可称为读取器或写入器)实现C++读写器锁?
- 如何在C 中自动汇总日志消息并自动解锁互斥X
- 如果我们已经手动解锁了unique_lock,那么破坏时会解锁吗?
- 正在解锁手动未定义/不良设计的锁定guard
- 从C 运行代码后解锁绑定(在R中)的问题
- 在功能返回之前,可以解锁Mutex会增加并发
- 当互斥锁解锁时,它会notify_all或notify_one
- 如何确保在C ++中解锁储物柜?哪种解决方案更好
- 我应该如何在一个功能中锁定wxMutex,并在另一个功能中将其解锁
- mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?
- 在Qt 5.4中可以对互斥对象进行两次解锁吗
- 当互斥锁/解锁深埋在函数调用中时,我需要栅栏或屏障或其他东西吗?