C++ 当互斥锁/解锁被深埋在函数调用中时,我是否需要围栏或屏障或其他东西?

C++ 当互斥锁/解锁被深埋在函数调用中时,我是否需要围栏或屏障或其他东西?,c++,concurrency,mutex,critical-section,C++,Concurrency,Mutex,Critical Section,我最近了解到,编译器将通过重新排列指令来优化代码,这可以通过使用屏障来控制 IIRC,锁定互斥锁会产生障碍,解锁互斥锁也会产生障碍,以防止关键部分内的代码泄漏 所以pthread_mutex_lock和pthread_mutex_unlock必须隐式地成为这些“屏障”。如果我有一个这样的类,它包装了我的互斥锁呢 class IMutex { public: virtual void lock() = 0; virtual void unlock() = 0; }; 在我看来,编

我最近了解到,编译器将通过重新排列指令来优化代码,这可以通过使用屏障来控制

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\u mutex\*()
,那么您的虚拟函数包含一个围栏

所以简单的回答是:不,它不会导致bug

还有volatile关键字,根据平台的不同,它也可以生成一个围栏。但是,使用volatile关键字会使检测这些围栏变得非常困难,因为每次使用volatile函数或变量时,都会引入围栏。因此建议您使用平台的同步功能


只有在不使用并发对象执行同步时(比如使用
bool
而不是互斥)才需要注意fences

我认为函数调用会阻碍编译器移动代码。我们使用互斥,不添加任何障碍。记忆障碍是另一回事。哦,这是有道理的。谢谢是的,没有一个健全的编译器会围绕虚拟函数调用重新排序…我不建议对数据成员使用volatile,因为它可能会引入内存隔离,这可能会再次隐藏数据竞争错误,因为“实际”互斥体有一些其他错误。。。使用适当的同步功能,而不是volatile。感谢@ActiveTrayPrntTagDataStrdrvr,我更新了答案以包含您的建议。