首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11:是什么阻止商店解除锁的关键部分的开始?

C++11:是什么阻止商店解除锁的关键部分的开始?
EN

Stack Overflow用户
提问于 2014-07-23 04:17:54
回答 1查看 350关注 0票数 3

我的理解是,可以使用C++11 atomics实现自旋锁,使用的是获取-CAS锁定和解锁上的发布存储,如下所示:

代码语言:javascript
运行
复制
class SpinLock {
 public:
  void Lock() {
    while (l_.test_and_set(std::memory_order_acquire));
  }

  void Unlock() {
    l_.clear(std::memory_order_release);
  }

 private:
  std::atomic_flag l_ = ATOMIC_FLAG_INIT;
};

考虑一下它在一个函数中的使用,该函数获取一个锁,然后对某个共享位置执行盲写:

代码语言:javascript
运行
复制
int g_some_int_;

void BlindWrite(int val) {
  static SpinLock lock_;

  lock_.Lock();
  g_some_int_ = val;
  lock_.Unlock();
}

我感兴趣的是编译器在将其转换为生成的程序集代码时是如何受到限制的。

我理解为什么对g_some_int_的写入不能迁移到编译器输出的关键部分的末尾--这意味着获取锁的下一个线程不能看到写入,而下一个线程通过发布/获取顺序来保证写入。

但是,是什么阻止编译器将其移动到锁标志的获取-CAS之前呢?我认为编译器可以在生成程序集代码时重新排序到不同的内存位置。是否有什么特殊的规则可以防止写入在程序顺序之前的原子存储之前被重新排序?

我正在找一个语言律师回答这里,最好涵盖std::atomicstd::atomic_flag

编辑,在评论中添加一些内容,这些评论可能会更清楚地提出问题。问题的核心是:标准的哪一部分要求抽象机器在写到l_之前必须观察falseg_some_int_

我怀疑答案要么是“写不能超越潜在的无限循环”,要么是“写不能高于原子写”。也许甚至是“你错了,写作可以被重新排序”。但我想在标准中找到具体的参考资料。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-23 08:33:07

假设您有两个使用自旋锁的函数:

代码语言:javascript
运行
复制
SpinLock sl;
int global_int=0;

int read(){
    sl.Lock();
    int res=global_int;
    sl.Unlock();
    return res;
}

void write(int val){
    sl.Lock();
    global_int=val;
    sl.Unlock();
}

如果两个对BlindWrite的调用同时发生在不同的线程上,那么一个(称为A)将获得锁;另一个(B)将在Lock中的循环中旋转。

然后写到g_some_int,然后调用Unlock,它包含对clear的调用,这是一个存储版本。在调用clear之前对写入进行排序,因为它位于同一个线程中。

B然后在Lock中唤醒,这一次test_and_set调用返回false。这是一个读取clear调用存储的值的负载获取,因此对clear的调用与对test_and_set的调用同步。

test_and_set调用在Lock中是一个加载-获取,并在BlindWrite中的g_some_int写入之前进行排序,因为它位于同一个线程中。

由于线程A中的第一次写入是排序的--在调用clear之前,这与线程B中对test_and_set的调用同步,而后者又是顺序的--在线程B的写入之前,线程A中的写入发生在线程B的写入之前。

如果编译器将对g_some_int的写挂在对Lock的调用之上,那么线程B的写入就有可能发生在线程A中的写入之前。这将违反发生的情况--在排序之前,因此是不允许的。

一般来说,这意味着编译器不能在负载获取()之上提升任何,因为它可能会在排序之前违反发生的情况。

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

https://stackoverflow.com/questions/24901772

复制
相关文章

相似问题

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