考虑以下示例:
bool lock(); // 由系统提供的函数
bool unlock(); // 由系统提供的函数
static int v = 0;
// 线程1
void invoke(){
lock();
v = 1; // #1
unlock();
}
// 线程2
void invoke2(){
lock();
v = 2; // #2
unlock();
}
假设lock
和unlock
是由系统提供的互斥锁(mutex)操作,它们能够防止代码行#1和#2之间产生数据竞争,前提是它们能建立“先发生”关系。然而,《C++标准》[intro.races]第10部分指出:
引用:
如果满足以下条件之一,则评估A在评估B之前发生(或等价地说,B在A之后发生):
- A在顺序上先于B;
- A与B之间存在线程间的先发生关系。
对于两个线程中的评估操作,我们期望同步操作来建立这种“先发生”关系。但是,同步的概念是针对标准库定义的,比如某些原子操作或std::mutex
。标准并未为非标准库明确定义同步概念。因此,从C++标准的角度来看,即使使用由系统提供的lock()
和unlock
函数,并且其API文档声称可以避免数据竞争,我们也无法确保它们具备同步性。
也就是说,只有标准库内的操作才能确保同步,因为标准明确规定了这一点。依赖于非标准库可能会导致未定义行为(UB),即便该库由系统提供并且其API文档说明可以避免数据竞争。