问题描述
嗨!
我正在实现一个线程化的生产者/消费者模式,只是为了好玩。我是
使用内部计数器来跟踪生产/消费的物品和
我正在记录这些信息。我正在使用Interlocked类增加一套
的计数器。
如果没有明确锁定对Interlocked类的调用,怎么回事
你得到正确的柜台价值吗?就我而言(感谢
,例如Jon Skeets网站和SDK上的优秀线程信息),
Interlocked.Increment允许更快的线程安全增加
共享变量 - 并降低应用程序的复杂性(这很好)。
int counter = 0 ;
//在某种方法中
Interlocked.Increment(ref counter);
Log.Write(" produ# {0}。",counter);
让我们假设大约有10个消费线程以相同的
时间运行。这可能会导致这样的情况,即调用
Log.Write会反映出一个刚被另一个
线程增加的值。下面的实现(以及实际上需要实际知道
在增量期间实际写入的值)似乎相当愚蠢
与对Interlocked类的轻量级调用相比。 />
//在某种方法中(使用锁)
int local = 0;
lock(_lock)
{
//在分配前增加
local = ++ counter;
Log.Write(" production #{0}。",local);
}
我可能会遗漏一些东西,但如果另一个计数器可能是
通过,有效地反映了递增的值。如下所示:
int counter = 0;
//在某些方法中
int local = 0 ;
Interlocked.Increment(ref counter,out local);
我已经完成的测试显示,你必须真的不走运,如果比赛
条件实际上会发生,但是锁定就是为了获取运气
等式(引用Jon Skeets网站) - 我同意。
提前致谢! :-)
-
关于
Anders Borum / SphereWorks
微软认证专家(.NET MCP)
Hi!
I am implementing a threaded producer / consumer pattern just for fun. I am
using an internal counter to keep track of the produced / consumed items and
am logging that information. I am using the Interlocked class to increment a
set of counter.
Without placing an explicit lock around calls to the Interlocked class, how
do you get the correct value of the counter? As far as I''m concerned (thanks
to the excellent threading information on e.g. Jon Skeets site and the SDK),
the Interlocked.Increment allows for a faster threadsafe incrementation of
shared variables - and reduces the complexity of your application (which is
nice).
int counter = 0;
// in some method
Interlocked.Increment(ref counter);
Log.Write("produced # {0}.", counter);
Let''s imagine that there are about 10 consuming threads running at the same
time. This could potentially lead to the situation, where the call to
Log.Write would reflect a value that''s just been incremented by another
thread. The following implementation (and the simple need to actually know
what value was actually written during incrementation) seems rather silly
compared to the lightweight call to the Interlocked class.
// in some method (using the lock)
int local = 0;
lock (_lock)
{
// increment before assignning
local = ++counter;
Log.Write("produced # {0}.", local);
}
I may be missing something, but it would be nice if another counter could be
passed, effectively reflecting the incremented value. Like the following:
int counter = 0;
// in some method
int local = 0;
Interlocked.Increment(ref counter, out local);
The tests I''ve done show, that you have to be really unlucky if the race
condition would actually occur, but locking is all about taking luck out of
the equation (to quote Jon Skeets site) - and I agree.
Thanks in advance! :-)
--
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)
推荐答案
如果宣布计数器是不稳定的,只需阅读它就足够了
。
否则,你可以调用CompareExchange:
int local = Interlocked.CompareExchange(ref counter,0,0);
基本上是如果值为
当前为0(即它是无操作),则会将值替换为0,但它*会返回原始值
:)
-
Jon Skeet - < sk *** @ pobox.com>
博客:
如果回复该群组,请执行不要给我发邮件
If the counter is declared to be volatile, just reading it should be
enough.
Otherwise, you could call CompareExchange:
int local = Interlocked.CompareExchange (ref counter, 0, 0);
Basically that will replace counter with the value 0 if the value is
currently 0 (i.e. it''s a no-op) but it *does* return the original value
:)
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
是的,但我最初是在增加的解决方案之后立即获得增值的值而不必发出锁定语句。
似乎Add()方法提供了所提出的解决方案的好处
与单(和高性能)方法调用。
Yes, but I was originally after the solution to incrementing and immediately
getting the incremented value without having to issue a lock statement.
Seems like the Add() method provides the benefit of the presented solutions
with a single (and high perf) method call.
一种有趣的方法 - 然而,易变是一种有趣的方法。接近并且只是阅读
这个变量看起来好一点了:)
-
关于
Anders Borum / SphereWorks
微软认证专家(.NET MCP)
An interesting approach - however, the "volatile" approach and just reading
the variable seems a bit nicer :)
--
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)
这篇关于从联锁操作中获取正确的价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!