在C++中,互斥锁保护数据的副本会被优化掉吗?

问题描述 投票:0回答:1

在 C++ 中,互斥锁保护数据的副本是否会被优化掉?

我想制作受保护数据的快照,并在互斥锁之外读取它。不过,这个副本是否会得到优化,让我要么读取互斥体内部的原始受保护数据(对性能不利),或更糟糕,读取互斥体外部的原始受保护数据(不安全)?

话题1

while (1)
{
  my_mutex.lock();
  data = ... /* Modifications to the data. */
  my_mutex.unlock();
  
  ... /* Unrelated stuff. */
}

话题2

while (1)
{
  my_mutex.lock();
  snapshot = data; /* Take a snapshot of the protected data. */
  my_mutex.unlock();
  
  ... /* Read various things in the snapshot. */
}
c++ multithreading optimization synchronization
1个回答
0
投票

互斥锁上的锁定和解锁操作充当内存屏障。在锁定之前或解锁之后,任何对象的读取或写入都不能重新排序。所以代码是安全的。

(一个例外是具有本地作用域的对象,其地址尚未传递到函数外部,因此没有其他线程可能同时访问它。)

从技术上讲,副本可以被优化,例如,如果您从未读取存储到

snapshot
中的值。编译器无法将
data
的读取移到临界区之外,但如果可以证明没有必要,它可以完全跳过读取。

还允许编译器从临界区内的

data
进行多次读取;这不会引入数据竞争,除非已经存在数据竞争。也许这对性能不利,但它是一致的; C++ 标准通常不强制要求性能。如果您的编译器生成次优代码,您必须直接处理它们。

© www.soinside.com 2019 - 2024. All rights reserved.