问题标签 [memory-visibility]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
391 浏览

c++ - C++11 原子。可见性和 thread.join() / 停止线程的正确方法

对于哪个(如果有的话?)STORE_ORDER& LOAD_ORDERC++11 是否保证此代码在有限时间内运行?

我看到两个问题:

内存顺序

在我看来,使用release& aquire,编译器和 cpu 可以在 之前重新排序 my join(假设它的行为像负载)store,这当然会破坏这一点。

即使使用memory_order_seq_cst,我也不确定是否禁止此类重新排序,因为我不知道是否join()真的进行了任何加载或存储。

能见度

如果我正确理解了这个问题memory_order_relaxed,则不能保证memory_order_relaxed在有限的时间内其他线程可以看到带有的商店。其他订单是否有这样的保证?

我知道这std::atomic是关于原子性和内存排序,而不是关于可见性。但我不知道 c++11 中的任何其他工具可以帮助我。我是否需要使用特定于平台的工具来获得正确性保证,如果是,是哪一个?


更进一步——如果我有有限性,那么对速度也有一些承诺会很好。我不认为 C++ 标准做出任何这样的承诺。但是是否有任何编译器或特定于 x86 的方法来保证存储将很快对其他线程可见?


总结:我正在寻找一种方法来快速停止实际上保证具有此属性的工作线程。理想情况下,这将与平台无关。但如果我们不能拥有它,它至少存在于 x86 中吗?

0 投票
3 回答
953 浏览

c++ - 原子操作传播/可见性(原子负载与原子 RMW 负载)

语境

我正在用 C++ 编写一个线程安全的原型线程/协程库,并且我正在使用原子来使任务切换无锁。我希望它尽可能高效。我对原子和无锁编程有一个大致的了解,但我没有足够的专业知识来优化我的代码。我做了很多研究,但很难找到我的具体问题的答案:不同内存顺序下不同原子操作的传播延迟/可见性是多少?

当前假设

我读到对内存的更改是从其他线程传播的,它们可能会变得可见:

  1. 对不同的观察者以不同的顺序,
  2. 一些延迟。

我不确定这种延迟的可见性和不一致的传播是否仅适用于非原子读取,或者也适用于原子读取,这可能取决于使用的内存顺序。当我在 x86 机器上开发时,我无法测试弱排序系统上的行为。

无论操作类型和使用的内存顺序如何,所有原子读取是否总是读取最新值?

我很确定所有读取-修改-写入(RMW)操作总是读取任何线程写入的最新值,而不管使用的内存顺序如何。对于顺序一致的操作似乎也是如此,但前提是对变量的所有其他修改也是顺序一致的。据说两者都很慢,这对我的任务不利。如果不是所有原子读取都获得最新值,那么我将不得不使用 RMW 操作来读取原子变量的最新值,或者在 while 循环中使用原子读取,据我目前的理解。

写入的传播(忽略副作用)是否取决于内存顺序和使用的原子操作?

(这个问题只有在前一个问题的答案是并非所有原子读取总是读取最新值时才有意义。请仔细阅读,我不在这里询问副作用的可见性和传播。我只关心原子变量本身的值。)这意味着根据用于修改原子变量的操作,可以保证任何后续原子读取都接收到变量的最新值。因此,我必须在保证始终读取最新值的操作之间进行选择,或者使用宽松的原子读取,同时使用这种特殊的写入操作来保证对其他原子操作的修改的即时可见性。

0 投票
1 回答
497 浏览

multithreading - 哪个 ARM 内存屏障保证两个线程之一将观察另一个线程所写的内容?

线程 A 和 B 正在同时执行。哪些 ARMv8-A 内存屏障类型(如 DMB、DSB)足以满足后置条件,为什么?


我查看了DMB 和 DSB 的 ARMv8-A 架构参考手册内存模型定义,但无法推断出为什么即使使用 DSB 内存屏障,后置条件也会成立。我认为架构参考手册中的关键定义是:

DMB 指令确保执行 DMB 的 PE 执行的所有受影响的内存访问,这些访问按程序顺序出现在 DMB 之前,以及源自不同 PE [...] 的那些在 DMB 执行之前已经被 PE 观察到的内存访问,在 DMB 之后按程序顺序出现的任何受影响的内存访问之前被每个 PE 观察到,被那个 PE 观察到。

当满足以下所有条件时,由 PE [...] 执行的 DSB 完成:

  • 在 DSB 之前按程序顺序出现的所需访问类型的所有显式内存访问对于所需共享域中的观察者集都是完整的。

  • [...]

此外,在 DSB 指令之后出现在程序顺序中的任何指令都不能改变系统的任何状态或执行其功能的任何部分,直到 DSB 完成,除了 [...]

0 投票
0 回答
131 浏览

java - CompletableFuture 的 thenAccept 保证可见性

我试图了解是否有任何可见性保证由CompletableFuture.

假设我有一个名为的类SampleClass,如下所示:

我做这样的事情:

现在,我想了解在sout声明中,是否存在成员之一或两个成员未初始化的情况?

基本上这里有提供任何可见性保证CompletableFuture吗?(我的印象是,CompletableFuture上面的代码没有提供这样的保证。)

我已经解决了这个问题,但我认为这不是我需要的。

0 投票
2 回答
105 浏览

java - 与 ConcurrentHashMap 的 .compute() 同步是否保证可见性?

ConcurrentHashMap.compute()I 内递增和递减位于共享内存中的一些 long 值。读取、递增/递减仅在compute同一键的方法内执行。因此,通过锁定 ConcurrentHashMap 段来同步对 long 值的访问,因此递增/递减是原子的。我的问题是:地图上的这种同步是否能保证长期价值的可见性?我可以依靠 Map 的内部同步还是应该做多volatile

我知道,当您明确同步锁定时,可以保证可见性。ConcurrentHashMap但是我对内部结构没有完全的了解。或者也许我今天可以信任它,但明天ConcurrentHashMap的内部结构可能会发生某种变化:独占访问权将被保留,但可见性将消失……这是使我的长期价值不稳定的论据。

下面我将发布一个简化的示例。根据测试,今天没有比赛条件。volatile但是我可以在没有for的情况下长期信任这个代码long value吗?

UPD:添加另一个更接近我正在处理的代码的示例。当没有其他人使用该对象时,我想删除地图条目。请注意,长值的读取和写入仅发生在重新映射函数内部ConcurrentHashMap.compute

UPD2:我承认我之前没有提供最简单的代码示例,现在发布一个真实的代码: