首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用锁进行指令重排序

使用锁进行指令重排序
EN

Stack Overflow用户
提问于 2016-09-29 14:21:20
回答 2查看 458关注 0票数 3

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

代码语言:javascript
复制
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();

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

代码语言:javascript
复制
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();
     }
....
}

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

避免重新排序的一种解决方案是使用memory barriers,但我正在尝试在mutex块中避免这种情况。

EN

回答 2

Stack Overflow用户

发布于 2016-09-29 14:25:13

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

您不能假设锁中的更新是在没有重新排序的情况下发生的。对updated的更新可能发生在x或y更新之前,如果你所有的访问都被锁定了,这应该不是问题。

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

票数 2
EN

Stack Overflow用户

发布于 2016-09-29 14:26:46

这就是锁定的保证,所以你不需要使用updated。顺便说一句,你应该锁定你的struct,而不是代码,每次你访问a时,你都应该先锁定它。

代码语言:javascript
复制
struct A{
  int x;
  int y;
}

A a;
std::mutex m_;   //Share this lock amongst threads

m_.lock();
a.x = 1;
a.y = 2;
m_.unlock();

在第二个线程中,你可以这样做

代码语言:javascript
复制
while(!stop)
{
  if(m_.try_lock()) {
    A* tmp = second_thread_copy_; 
    second_thread_copy_ = first_thread_copy_;
    first_thread_copy_ = tmp;
    m_.unlock();
  }
}

编辑:因为你正在重写struct,所以在其中包含互斥锁是没有意义的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39762802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档