std::mutex 是否强制缓存内聚?

Does std::mutex enforce cache cohesion?

我有一个非原子变量 my_var 和一个 std::mutex my_mut。我假设在代码中到目前为止,程序员遵循了这个规则:

Each time the programmer modifies or writes to my_var, he locks and unlocks my_mut.

假设如此,Thread1 执行以下操作:

my_mut.lock();
my_var.modify();
my_mut.unlock();

这是我在脑海中想象的事件顺序:

  1. my_mut.lock();之前,主内存和一些本地缓存中可能有多个my_var的副本。这些值不一定一致,即使程序员遵循了规则。
  2. 通过指令 my_mut.lock();,来自先前执行的 my_mut 临界区的所有写入对该线程在内存中可见。
  3. my_var.modify(); 执行。
  4. my_mut.unlock();之后,主存和部分本地缓存中可能存在my_var的多个副本。这些值不一定一致,即使程序员遵循了规则。下一个锁定 my_mut 的线程在锁定 my_mut.
  5. 时,该线程末尾的 my_var 的值将可见

我一直无法找到一个来源来验证这正是 std::mutex 应该如何工作。我查阅了C++标准。从ISO 2013,我找到了这个部分:

[ Note: For example, a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A.

我对std::mutex的理解正确吗?

C++ 对操作之间的关系进行操作,而不是某些特定的硬件术语(如缓存内聚)。所以 C++ 标准有一个 happens-before 关系,这大致意味着 之前发生的任何事情都完成了它的所有 side-effects,因此是可见的在之后发生的那一刻。

如果您有一个您进入的独占关键会话,则意味着无论其中发生什么,都会在下次进入此关键部分之前发生。所以任何进入它的人都会看到之前发生的一切。这就是标准的要求。其他一切(包括缓存内聚)都是实现的职责:它必须确保所描述的行为与实际发生的行为一致。