读取是由互锁的其他线程更新一个int [英] Reading an int that's updated by Interlocked on other threads

查看:226
本文介绍了读取是由互锁的其他线程更新一个int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这是一个重复:如何正确阅读一个Interlocked.Increment'ed INT场?但是,阅读的答案和评论后,我仍然不知道正确的答案的。)

(This is a repeat of: How to correctly read an Interlocked.Increment'ed int field? but, after reading the answers and comments, I'm still not sure of the right answer.)

有一些代码,我没有自己,不能改变使用增量在几个不同的线程一个int计数器(numberOfUpdates)锁。所有呼叫使用:

There's some code that I don't own and can't change to use locks that increments an int counter (numberOfUpdates) in several different threads. All calls use:

Interlocked.Increment(ref numberOfUpdates);



我想在我的代码读取numberOfUpdates。现在,因为这是一个int,我知道,它不能撕裂。但是,什么是保证我得到的最新值最好的方式?这似乎是我的选择是:

I want to read numberOfUpdates in my code. Now since this is an int, I know that it can't tear. But what's the best way to ensure that I get the latest value possible? It seems like my options are:

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

int localNumberOfUpdates = Thread.VolatileRead(numberOfUpdates);



都将工作(在考虑提供优化,重新排序的最新值可能的感觉,缓存,等等)?是一种优选的比其他?是否有更好第三种选择?

Will both work (in the sense of delivering the latest value possible regardless of optimizations, re-orderings, caching, etc.)? Is one preferred over the other? Is there a third option that's better?

推荐答案

我在那的坚定信仰者,如果你正在使用互锁递增共享数据,那么你应该使用互锁无处不在,你该共享数据访问。同样,如果你使用的插入你最喜欢的同步原语在这里的递增共享数据,那么你应该使用的插入你最喜欢的同步原语在这里的无处不在,你访问共享数据。

I'm a firm believer in that if you're using interlocked to increment shared data, then you should use interlocked everywhere you access that shared data. Likewise, if you use insert you favorite synchronization primitive here to increment shared data, then you should use insert you favorite synchronization primitive here everywhere you access that shared data.

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



会给你寻找什么。正如其他人所说联锁操作都是原子。所以Interlocked.CompareExchange总是返回最近的值。我用这一切来访问计数器一样简单的共享数据的时间。

Will give you exactly what your looking for. As others have said interlocked operations are atomic. So Interlocked.CompareExchange will always return the most recent value. I use this all the time for accessing simple shared data like counters.

我不熟悉Thread.VolatileRead,但我怀疑它也将返回最近的值。我会用互锁方法坚持下来,哪怕只是被一致着想。

I'm not as familiar with Thread.VolatileRead, but I suspect it will also return the most recent value. I'd stick with interlocked methods, if only for the sake of being consistent.

附加信息:

我建议你服用看乔恩斯基特的答案,为什么你可能希望从Thread.VolatileRead()回避: Thread.VolatileRead实施

I'd recommend taking a look at Jon Skeet's answer for why you may want to shy away from Thread.VolatileRead(): Thread.VolatileRead Implementation

埃里克利珀讨论波动性和在的 http://blogs.msdn.com/b/ericlippert /archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx 。直接从马嘴:真正的专家,我不尝试写入除联锁操作的最简单的用法任何低锁码我离开的使用挥发性

Eric Lippert discusses volatility and the guarantees made by the C# memory model in his blog at http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx. Straight from the horses mouth: "I don't attempt to write any low-lock code except for the most trivial usages of Interlocked operations. I leave the usage of "volatile" to real experts."

和我同意汉斯的点值将始终是陈旧的,至少由几个纳秒,但如果你有一个使用的情况下是不能接受的,它可能并不适合一个垃圾收集语言一样C#或非实时操作系统。乔·达菲在这里有上互锁方法的时效性好的文章:的 http://joeduffyblog.com/2008/06/13/volatile-reads-and-writes-and-timeliness/

And I agree with Hans's point that the value will always be stale at least by a few ns, but if you have a use case where that is unacceptable, its probably not well suited for a garbage collected language like C# or a non-real-time OS. Joe Duffy has a good article on the timeliness of interlocked methods here: http://joeduffyblog.com/2008/06/13/volatile-reads-and-writes-and-timeliness/

这篇关于读取是由互锁的其他线程更新一个int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆