c++ - 带锁的指令重排序

标签 c++ multithreading

编译器会重新排序由 mutex 保护的指令吗?我正在使用一个 boolean 变量来决定一个线程是否更新了某个结构。如果编译器对指令重新排序,则可能会在更新结构的所有字段之前设置 boolean 变量。

struct A{
  int x;
  int y;
  // Many other variables, it is a big struct
}

std::mutex m_;
bool updated;
A* first_thread_copy_;
// a has been allocated memory

m_.lock();
first_thread_copy_->x = 1;
first_thread_copy_->y = 2;
// Other variables of the struct are updated here
updated = true;
m_.unlock();

在另一个线程中,我只是检查结构是否已更新并交换指针。

while (!stop_running){

    if (updated){
        m_.lock();
        updated = false;
        A* tmp = second_thread_copy_; 
        second_thread_copy_ = first_thread_copy_;
        first_thread_copy_ = tmp;
        m.unlock();
     }
....
}

我的目标是让第二个线程尽可能快。如果它发现更新没有发生,它会继续并使用旧值来完成剩下的事情。

避免重新排序的一种解决方案是使用内存屏障,但我试图在mutex block 中避免它。

最佳答案

您可以安全地假设指令在锁定/解锁和锁内指令之间没有重新排序。 updated = true 不会发生在解锁之后或锁定之前。两者都是障碍,并防止重新排序。

您不能假设锁内的更新会在不重新排序的情况下发生。 updated 的更新可能发生在 x 或 y 的更新之前。如果您的所有访问权限也都处于锁定状态,那应该不是问题。

考虑到这一点,请注意,可能重新排序指令的不仅仅是编译器。 CPU 也可能乱序执行指令。

关于c++ - 带锁的指令重排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39762802/

相关文章:

c++ - 移动构造函数不移动

c++ - 通过多个定界符解析 C++ 中的字符串

multithreading - 管理多进程 : What are the common strategies?

c# - 为什么并发修改数组这么慢?

c++ - 有什么方法可以从 C++ 中的文本中提取 URL

c++ - Directx : HLSL Texture based height map.(着色器 5.0)

c++ - boost::log 在 channel 记录器中设置 "Channel"属性

java - 提高欧拉数并行计算的性能

c - 第一次在 C 中使用 pthreads,为什么这些线程没有返回任何内容?

java - 如何调试 JVM 中的挂起线程?