我听说单个原子操作是线程安全的,因为当一个核心正在处理一个原子操作时,它在完成原子操作之前不会做任何其他事情。
例如,在32位操作系统中的java中,有一个变量可以被多个线程访问
int a; 线程1写入
a = 3; 线程2可以写
a = 4; 写入该变量的线程顺序可能会发生变化,因此最终值可以是3或4,但我们可以确保写入int是一个原子操作,因此该变量中的32位不会混入到某个不可预测的数字中。
我知道在单个核心环境中是这样的,因为在确定原子操作完成之前,核心不会执行另一个线程的代码,
然而,在多核环境中,难道另一个核心不可能访问当前核的原子操作下的变量吗?从而导致变量中的32位混淆?
发布于 2016-03-03 11:36:04
不-这就是原子的意思:写总是成功的“没有干扰”。因此,您将读取0(原始值)、3或4,但不读取其他值。
在多核设置中,如果线程T1在核心C1上写3,而线程T2在核心C2上写4,那么这个值可能只对写的核心可见。因此,您的int在C1中的值可能是3,在C2中的值可能是4。如果有第三个核心C3,它仍然可以看到原始值0。
为了防止这种不一致性,您需要添加一些同步(例如,通过使int易失性)。
发布于 2016-03-03 11:47:07
简而言之,没有一个示例操作是线程安全的。您需要使用atomics或同步来获得任何可预测的输出。在给定的示例中,甚至有可能在读取线程'a‘时,它将被定义为0,并将被更新为'3’或'4‘。
原子学不仅与原子性有关,还与有序性有关。后者是所有并发编程的基石。
请记住,有许多事情可能出错,这不仅仅是CPU中正在发生的事情。编译器还会重新排序操作,甚至消除主内存写入。
我建议阅读以下链接来了解所有这些内容是如何工作的:
https://stackoverflow.com/questions/35770941
复制相似问题