读取由其他线程上的Interlocked更新的int

迈克尔·科维利

(这是以下内容的重复:如何正确读取Interlocked.Increment'ed int字段?但是,在阅读了答案和评论之后,我仍然不确定正确的答案。)

我不拥有一些代码,不能更改为使用在多个不同线程中增加int计数器(numberOfUpdates)的锁的代码。所有通话都使用:

Interlocked.Increment(ref numberOfUpdates);

我想在代码中阅读numberOfUpdates。现在,由于这是一个整数,所以我知道它不会撕裂。但是,确保我能获得最新价值的最佳方法是什么?看来我的选择是:

int localNumberOfUpdates = Interlocked.CompareExchange(ref numberOfUpdates, 0, 0);

要么

int localNumberOfUpdates = Thread.VolatileRead(numberOfUpdates);

两者都可以工作(在不考虑优化,重新排序,缓存等的情况下,尽可能提供最新的价值)吗?一个比另一个更好吗?还有第三种更好的选择吗?

帕特·汉塞尔

我坚信如果您使用互锁来增加共享数据,那么在访问共享数据的任何地方都应该使用互锁。同样,如果在此处使用“插入您喜欢的同步原语”来增加共享数据,那么访问共享数据的任何地方都应在此处使用“插入您喜欢的同步原语”

int localNumberOfUpdates = Interlocked.CompareExchange(ref numberOfUpdates, 0, 0);

会给您您想要的东西。正如其他人所说,互锁操作是原子的。因此,Interlocked.CompareExchange将始终返回最新值。我一直在使用它来访问简单的共享数据(例如计数器)。

我对Thread.VolatileRead不太熟悉,但我怀疑它还会返回最新值。如果只是为了保持一致,我会坚持使用互锁的方法。


附加信息:

我建议您看一下乔恩·斯基特(Jon Skeet)的答案,为什么您可能想回避Thread.VolatileRead():Thread.VolatileRead实现

埃里克·利珀特(Eric Lippert)在其博客(http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different)中讨论了波动性和C#内存模型所提供的保证。-part-three.aspx直截了当:“除互锁操作的最简单用法外,我不尝试编写任何低锁代码。我将“ volatile”的用法留给真正的专家使用。”

我同意Hans的观点,即该值至少会过时数ns,但是如果您有一个用例不可接受,那么它可能不太适合像C#或非真实的垃圾收集语言时间操作系统。Joe Duffy在这里有一篇很好的文章,介绍了互锁方法的及时性:http : //joeduffyblog.com/2008/06/13/volatile-reads-and-writes-and-timeliness/

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从其他线程读取值

从其他线程更新UI

从其他线程更新 AtomicInteger

从其他线程读取图像的正确方法

为什么读取由其他线程修改的变量既不是旧值也不是新值

强制解锁由其他线程锁定的互斥锁

静态内存是否由其他线程清除?

需要更新变量,主线程还是其他线程?

Python - 如何在其他线程的线程上暂停?

Spark Dataframe上的滚动总和由其他列过滤

Android:根据其他线程触发的事件更新 GUI

Python Tkinter变量未在其他线程中更新

JavaFX-从其他线程更新标签值

VB.net 从其他线程更新标签

其他线程上的C#执行方法

Qt-在其他线程上运行功能

其他线程堆栈上的空闲内存无效

在Linux上,TLS是由内核还是由libc(或其他语言运行时)设置的?

即使同步块中的其他线程更新,线程也无法获得最新值?

为什么主线程不能比较其他线程更新的两个变量?

C#:读取由其他换行符分隔的文本文件

sem_wait上的线程阻塞导致其他线程挂起

在Java中,当文件被其他线程锁定时,是否可以读取该文件?

当其他线程正在等待读取时,对串行端口的写入将永远被阻塞

读取 volatile 变量会影响线程缓存中其他非 volatile 变量的值吗?

Python 多处理:“self.”变量未在其他函数中/由其他函数更新?

从WPF中的其他线程更新UI控件时,出现“调用线程无法访问该对象,因为其他线程拥有该对象”错误

在jQuery .html()更新上,其他功能停止工作

在其他ListView的SelectionChanged事件上更新ListView