仅使用互斥锁来保护对齐的 uint64 访问是否有意义?

yac*_*c45 1 c++ x86 synchronization mutex locking

我在一些生产代码中看到过如下所示的 C++ 代码。假设 x 与 uint64 对齐并且代码在 X86 系统上运行。我的理解是,在 x86 系统上读取/写入对齐的 uint64 值是原子的。那么这里额外的互斥体的目的是什么?

当调用 GetX() 时持有互斥锁时,其他一些线程可以在 GetX() 之前/之后获取互斥锁并更改 X。所以我不认为额外的互斥体会让代码更安全。

uint64 GetX()
{
   Mutex l(&mutex); (1)
   return x;
}
Run Code Online (Sandbox Code Playgroud)

use*_*522 5

ISA 级别上的等效访问是否是原子的并不重要。你不能违反 C++ 内存模型。编译器会在不违反的假设下进行优化。

特别是,std::atomic在 C++ 模型中,只有特化是原子类型。对任何其他对象类型(至少有一个写入)的任何不同步访问都是 C++ 模型中的数据争用,因此会导致未定义的行为。

x因此,如果的类型不是特化,则需要在读取变量之前锁定互斥锁std::atomicx但是,如果是这样,可以通过改为避免这种情况std::atomic。那么,无论 ISA 级别上的等效访问是否是原子的,都不会导致数据争用。std::atomic(如果硬件不直接支持,编译器必须使用内部锁来实现原子性。)


话虽如此,正如您所暗示的那样,该功能似乎并不是特别有用。一旦它返回, 的值x可能已经改变,因此调用者不能假设它仍然保留该值。然而,如果没有锁定,代码将具有未定义的行为,这比仅仅提供无用的值更糟糕。


归档时间:

查看次数:

103 次

最近记录:

3 年,5 月 前