linq - Why decrementing one variable modifies incrementing of another one in C# Parallel.ForEach loop? -
running code parallel.foreach keeps spawning new threads few modifications
the output commented line:
//threadsremaining = interlocked.decrement(ref concurrentthreads);
is "obvious", i.e. expected one:
[00:00] job 0 complete. 2 threads remaining. unsafecount=2 [00:00] job 1 complete. 1 threads remaining. unsafecount=1 [00:00] job 2 complete. 3 threads remaining. unsafecount=3 [00:00] job 3 complete. 4 threads remaining. unsafecount=4 [00:00] job 4 complete. 5 threads remaining. unsafecount=5 [00:00] job 5 complete. 6 threads remaining. unsafecount=6 [00:01] job 6 complete. 7 threads remaining. unsafecount=7 [00:01] job 8 complete. 8 threads remaining. unsafecount=8 [00:01] job 7 complete. 9 threads remaining. unsafecount=9 [00:01] job 9 complete. 10 threads remaining. unsafecount=10
while output of same code upon uncommenting above line is:
[00:00] job 0 complete. 1 threads remaining. unsafecount=1 [00:00] job 1 complete. 0 threads remaining. unsafecount=0 [00:00] job 3 complete. 0 threads remaining. unsafecount=0 [00:00] job 2 complete. 1 threads remaining. unsafecount=1 [00:00] job 4 complete. 1 threads remaining. unsafecount=1 [00:00] job 5 complete. 1 threads remaining. unsafecount=1 [00:01] job 6 complete. 1 threads remaining. unsafecount=1 [00:01] job 8 complete. 1 threads remaining. unsafecount=1 [00:01] job 9 complete. 1 threads remaining. unsafecount=1 [00:01] job 7 complete. 0 threads remaining. unsafecount=0
can explain me why decrementing 1 variable threadsremainin
stops (or prevents) incrementing 1 unsafecount
?
the code of console app:
using system; using system.collections.generic; using system.linq; using system.threading; using system.threading.tasks; namespace separallelforeachkeepsspawningnewthreads { public class node { public node previous { get; private set; } public node(node previous) { previous = previous; } } public class program { public static void main(string[] args) { datetime startmoment = datetime.now; int concurrentthreads = 0; int unsafecount = 0; var jobs = enumerable.range(0, 10); paralleloptions po = new paralleloptions { maxdegreeofparallelism = environment.processorcount }; parallel.foreach(jobs, po, delegate(int jobnr) { int threadsremaining = interlocked.increment(ref concurrentthreads); unsafecount++; int heavyness = jobnr % 9; //give processor , garbage collector do... list<node> nodes = new list<node>(); node current = null; //for (int y = 0; y < 1024 * 1024 * heavyness; y++) (int y = 0; y < 1024 * 4 * heavyness; y++) { current = new node(current); nodes.add(current); } timespan elapsed = datetime.now - startmoment; //***************** //threadsremaining = interlocked.decrement(ref concurrentthreads); console.writeline("[{0:mm\\:ss}] job {1} complete. {2} threads remaining. unsafecount={2}", elapsed, jobnr, threadsremaining, unsafecount); }); console.writeline("finished"); console.readline(); } } }
this problem:
console.writeline( "[{0:mm\\:ss}] job {1} complete. {2} threads remaining. unsafecount={2}", elapsed, jobnr, threadsremaining, unsafecount);
the final part should {3}
, not {2}
. you're printing out threadsremaining
twice @ moment...
Comments
Post a Comment