当前位置: 首页 > 知识库问答 >
问题:

发布/获取语义wrt std::互斥

霍伟彦
2023-03-14

我正在阅读n3485中定义的C内存模型,它讨论了释放/获取语义,根据我的理解,以及本博客中给出的定义:

Acquire语义是一个属性,它只能应用于从共享内存读取的操作,无论是读-修改-写操作还是普通加载。然后,该操作被视为读取获取。Acquire语义可以防止读Acquire的内存重新排序,并按照程序顺序执行读或写操作。

释放语义学是一个属性,它只适用于写入共享内存的操作,无论它们是读-修改-写操作还是普通存储。然后将该操作视为写-释放。释放语义学防止写-释放的内存重新排序,任何读或写操作都按照程序顺序在它之前。

将阻止在当前读/写操作完成之前或之后重新排序读/写操作。第一个(获取)将确保当前正在进行的读操作不会因其后的任何读/写操作而重新排序,后一个(释放)将确保当前写操作不会因之前的读/写操作而重新排序。

现在可以说,std::mutex::lock将具有获取语义,而std::mutex::unlock本质上具有释放语义吗?

在标准中,我可以在第节中找到这一点

30.4.1.2互斥类型[thread.mutex.requirements.mutex]

11同步:对同一对象的先前lock()操作应与(1.10)此操作同步。

从我的理解来看,标准中没有明确定义同步,但它似乎是一种先发生后关系,查看两个不同线程之间正在计算的两条语句,然而,从我对获取/释放语义的理解来看,这与内存重新排序有更大关系。与同步也可以称为释放/获取语义?

那么,释放/获取语义学不仅适用于加载/存储操作的重新排序,也适用于操作的线程内交织吗?

在关于内存模型的标准部分中,它主要讨论两个线程交错的有序关系。对于这是否也适用于内存排序,这还有待解释。

有人能澄清一下吗?

共有1个答案

亢琦
2023-03-14

现在可以说std::mutex::lock将具有获取语义,而std::mutex::unlock本质上具有释放语义吗?

是的,这是正确的。

据我所知,同步在标准中没有明确定义

理论上,第1.10/8段可能是为了给出同步的定义:

某些库调用与其他线程执行的其他库调用同步。例如,原子存储释放与从存储中获取其值的load acquire同步(29.3)。[注:…]

另一方面,这听起来不像是一个非常正式的定义。然而,第1.10/10段间接给出了一个更好但隐含的定义:

如果满足以下条件,则评估A在评估B之前排序依赖关系

-A对原子对象M执行释放操作,而在另一个线程中,B对M执行消耗操作,并读取由A开头的释放序列中的任何副作用写入的值,或

-对于某些评估X,A在X之前是依赖排序的,并且X对B具有依赖关系。

[注:关系“是之前排序的依赖关系”类似于“与同步”,但使用release/-consume代替release/acquire。-结束说明]

由于“类似于”关系通常是对称的,所以我想说上面的“依赖排序”定义也间接提供了“同步”的定义——尽管您可能会正确地反对注释是非规范性的;尽管如此,这似乎是预期的定义。

我对同步关系的直觉是,它发生在存储某个值的一个线程执行的写入(原子)操作和读取该值的第一个(原子)操作之间。那个操作可能在同一个线程中。

如果这两个操作在不同的线程上,那么synchronizes with关系将在操作上建立跨线程排序。

在标准中,我可以在第节中找到这一点

30.4.1.2互斥类型[thread.mutex.requirements.mutex]

11同步:对同一对象的先前lock()操作应与(1.10)此操作同步。

对我来说,这似乎与上面给出的解释相符。具有释放语义(解锁、存储)的操作将与获取语义(锁定、加载)的操作同步。

然而,从我对获取/释放语义学的理解来看,这更多地与记忆重组有关。

释放和获得语义学描述了一些操作的性质;同步关系(实际上)是在已经获得或释放语义学的操作之间建立的一种关系,以一种明确的方式。

因此,从某种意义上说,与同步是这些操作语义的结果,我们使用这些语义来实现指令的正确排序,并约束CPU或编译器可能执行的重新排序。

 类似资料:
  • 假设我有一个时间戳计数器。 假设我有一些并发代码,我想通过实验测试和记录内存重新排序。 在c11内存模型下,do\u a可能会被重新排序,超过get\u ts,使用do\u b()。 但是,假设编译器没有在x86上重新排序锁xadd,则会阻碍所有加载和存储。因此,事实上x86(但不是编译器)不可能进行这种重新排序,因为get\ts调用充当了一个获取释放界限。 在x86上有没有办法实现真正的acqu

  • 我使用fetchapi发布表单中的一些数据,这很有效。 但是我面临一个问题,问题是当我发布数据时,状态不会更新,是的,我知道我没有使用setState(),但没有设置它。然而 目前,我正试图通过控制台日志来调试该问题,结果发现没有使用主体。 提交功能: 这是第一次使用提取API。Tm真的很困惑为什么这行不通,任何帮助都将不胜感激。我知道链接。然后(),但我不能让它与POST请求一起工作。 我想做的

  • 问题内容: 是什么区别 GET 和 POST 的 Ajax的 请求? 我看不到这两者之间的任何区别,除了当我使用 GET时 ,参数是在URL中发送的,这对我来说并没有任何区别,因为所有请求都是在后台进行的,并且用户找不到任何请求区别。 编辑:什么是 PUT 和 DELETE 方法? 问题答案: GET设计用于从服务器获取数据。POST(以及鲜为人知的朋友PUT和DELETE)设计用于修改服务器上的

  • 我如何获得所有的发布组和发布日期的艺术家在一个电话与musicbraz api?我能做到这一点的最接近的方法是使用: 但是,有些发布组不存在。例如,使用上面的调用,“EP”、“单混音”和一些非官方版本都没有出现。基本上,我希望能够制作与musicbrainz相同的列表,当你进入艺术家的主页进行“所有”发行时: 此外,上面的api调用不返回发布日期。有什么建议吗?这些是虫子吗?报告此事的最佳地点是哪

  • 我在Mac El Capitan上使用Android Studio。如何获取放行证书指纹?我需要火力点。我不确定到底怎么弄到它。

  • 似乎获得和释放语义学的公认定义是这样的:(引用自http://msdn.microsoft.com/en-us/library/windows/hardware/ff540496(v=vs.85). aspx) 如果其他处理器总是在任何后续操作的效果之前看到其效果,则该操作具有acquire语义。如果其他处理器在操作本身的效果之前看到前面每个操作的效果,则操作具有释放语义。 我简单地读过关于半记忆