问题标签 [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 投票
1 回答
132 浏览

c++ - 如果只有一个 CPU 内核,每个线程是否也存在内存可见性问题?

标题可能看起来很奇怪,所以让我解释一下。经常有人讲授竞争条件,说线程 1 可以看到x == 0,而线程 2 已经看到了x=1;

我的问题是关于在同一个核心上调度的线程(并非不切实际,仍然有 1 个核心嵌入式系统,并且至少在理论上您可以将线程绑定到核心):
即使线程 1 和线程 2 按顺序运行,也会出现常见的竞争可见性问题(在同一个核心(X86,ARM)上一个之前/之后(与其他线程的c))...

0 投票
3 回答
715 浏览

java - 并发 C++ 程序中的可见性

我知道在 Java 中,从另一个线程访问成员时不能保证成员的可见性。

意思是访问线程可能会看到成员的窃取值(因为缓存尚未刷新到主内存)。

我想知道 C++ 是否也是这种情况?(也在 C++11 中?)

如果是这样,你如何在 C++ 中解决这个问题?(在 Java 中,您可以使用 synchronized 关键字)。

0 投票
1 回答
342 浏览

java - 使用 volatile 确保 Java 中共享(但不是并发)数据的可见性

我正在尝试实现 LZ77 的快速版本,我有一个关于并发编程的问题要问你。

现在我有 afinal byte[] buffer和 a final int[] resultHolder,两者的长度相同。该程序执行以下操作:

  1. 主线程写入所有缓冲区,然后通知线程并等待它们完成。

  2. 单个工作线程处理缓冲区的一部分,将结果保存在结果持有者的同一部分中。工人的部分是独家的。之后通知主线程并且工作人员暂停。

  3. 当所有工作人员都暂停后,主线程读取 resultHolder 中的数据并更新缓冲区,然后(如果需要)该过程再次从点 1 开始。

管理器(主线程)中的重要内容声明如下:

MemoryHelper 简单地包装了一个 volatile 字段并提供了两种方法:一种用于读取它,另一种用于写入它。

工人的 run() 代码:

最后,主线程的重要部分:

ArrayBlockingQueue 上的同步效果很好。我的疑问在于使用readVolatile()and writeVolatile()。有人告诉我,写入 volatile 字段会将所有先前更改的数据刷新到内存中,然后从另一个线程读取它会使它们可见。

那么在这种情况下是否足以确保正确的可见性?永远不会对相同的内存区域进行真正的并发访问,因此 volatile 字段应该比 ReadWriteLock 便宜很多。

0 投票
3 回答
587 浏览

java - 易失性数组 - 元素的内存可见性

考虑代码片段

}

问题:Object oneTask = localTasksArray[someindex];对于 Object oneTask 的内存可见性,操作是否安全?oneTask 是否可能显示为 null 或处于预期之外的其他状态?

我的想法是:

thread2 可能会oneTask被视为 null 或处于预期之外的某种状态。这是因为,即使taskArrayvolatile,并且对该数组的读取将确保数组本身的正确可见性,但这并不能确保对象内部状态的可见性oneTask

0 投票
2 回答
139 浏览

c# - BackgroundWorker 是否保证在后台线程上所做的内存更改对主线程可见?

如果我使用 BackgroundWorker 修改应用程序中的数据结构,是否可以保证在 BackgroundWorker 完成时(例如在 RunWorkerCompleted 事件处理程序中)对主 (UI) 线程可见对后台线程所做的更改?对于奖励积分:如果是这样,保证这一点的机制是什么?

0 投票
3 回答
191 浏览

multithreading - Perl ithreads:共享变量 - 多处理器内核线程 - 可见性

perlthrtut 摘录:

请注意,共享变量保证如果两个或多个线程同时尝试修改它,变量的内部状态不会被破坏。但是,除此之外没有任何保证,如下一节所述。

在支持多处理器内核线程的 Linux 上工作。

是否保证所有线程都会看到更新的共享变量值?如上所述咨询 perlthrtut 文档没有这样的保证。

现在的问题是:可以以编程方式做些什么来保证这一点?

0 投票
2 回答
192 浏览

java - Java 并发集合和可见性

我有点不确定从并发集合(例如 ConcurrentMap)中对集合中数据的可见性的期望。

A: Thread1 放入一个复杂对象,Thread2 得到它。所有属性在 Thread2 中都可见吗?

B:Thread1 放了一个复杂的对象,后来改变了一些属性。然后 Thread2 得到它,在 Thread2 中会不会所有的变化都是可见的?

我猜 B 是假的,如果是这样,我应该同步对复杂对象的每次访问?

0 投票
3 回答
511 浏览

java - 需要挥发物吗?

如果我有一个字节队列,预计会有一个线程生产者,另一个消费者:

这种类型的队列不需要同步。
readIdx 仅由 reader 线程修改,
writeIdx 仅由 writer 线程修改。

readIdx == writeIdx 表示,没有内容。
而且队列最多只能占用 buf.length-1 字节的数据。

是否需要 volatile 或者是否可以省略它们,因为只有一个线程是一个整数状态的修饰符?

谢谢弗兰克

0 投票
2 回答
297 浏览

java - java并发编程中的可见性问题

我在“Java Concurrency in Practice”一书中遇到了以下示例。

其进一步说明为:

NoVisibility 可能永远循环,因为ready 的值可能永远不会对阅读器线程可见。更奇怪的是,NoVisibility 可以打印零,因为在写入 number 之前,ready 的写入可能对 reader 线程可见,这种现象称为重新排序。

我可以理解重新排序问题,但我无法理解可见性问题。为什么ready可能永远不会对读者线程可见?一旦主线程将值写入ready,阅读器线程迟早会有机会运行并且可以读取 的值ready。为什么主线程所做的更改ready可能对阅读器线程不可见?

0 投票
3 回答
353 浏览

java - 能见度保证

我已经阅读了JCIP对第16.3节“初始化安全”的一些解释,但仍然不清楚。该部分指出

“此外,可以通过正确构造的对象的最终字段(例如最终数组的元素或最终字段引用的 HashMap 的内容)访问的任何变量也保证对其他线程可见。”

因此,如果我有以下可变对象:

然后,线程 1如下创建它并将 c 传递给Thread2

Thread2(不是并发的,让我们说在 1 ms 之后),读取 c 的值,Thread2 是否可能会看到

干杯

更新

我注意到有一些关于类有吸气剂的困惑。我正在更新源代码,希望这会很清楚。谢谢大家看看。

//------------

//----

我的问题是:

a) 当Thread2调用 consume() 时,name、cupsWon、netWorth 可以为 null、0 还是 0.0?我的想法是它可以,因为 Container 类中的字段不是最终的,因此没有可见性保证

b)但是,然后我阅读了第 16.3 节和有关“可以通过正确构造的对象的最终字段到达的变量”的内容,这是否意味着因为容器 c 的实例被声明为最终的,所以我们确实可见性保证消耗()?

final Container c = new Container("Ted Dibiasi", 10, 1000000);

c) 将 Client 类中对 Container 的引用声明为 volatile 不会解决与引用相关的字段的可见性问题。