A
Anders Borum
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!
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!