c# - multi-threaded increment and skip 0 without a lock? -
i have ushort counter (that rolls over). messaging protocol uses value disallows 0. need thread-safe way increment counter (stored in class field) every time read it, isn't hard if store int , use interlocked.increment. however, i'm not sure how incorporate skipping 0 that. it's okay if skip few numbers; output sequence doesn't have perfect. cannot ever reuse same number in block of 4000. avoid using lock.
this one:
given:
static int value = ushort.maxvalue;
and in code:
int temp, temp2; { temp = value; temp2 = temp == ushort.maxvalue ? 1 : temp + 1; } while (interlocked.compareexchange(ref value, temp2, temp) != temp);
you'll have use int
, cast (for example in get
property), because interlocked
aren't basic types.
we make little faster in highly threaded contexts this:
int temp = value; while (true) { int temp2 = temp == ushort.maxvalue ? 1 : temp + 1; int temp3 = interlocked.compareexchange(ref value, temp2, temp); if (temp3 == temp) { break; } temp = temp3; }
in way have 1 less read on failure.
as i've written in comment, central idea of code increment in temporary variable (temp2
) counter, , trying exchange old value know new value (interlocked.compareexchange
). if no 1 touched old value in-between (interlocked.compareexchange() == temp
) have finished. if else incremented value try. ushort
simulated use of int
fixed maximum value (temp == ushort.maxvalue ? 1 : temp + 1
).
the second version, on failure of interlocked.compareexchange()
reuses value read function new basis on add 1.
the interlocked.compareexchange
used in way can used basis building other interlocked
operations (you want interlocked.multiply
? "standard" multiply , try interlocked.compareexchange
old value)
Comments
Post a Comment