multithreading - C# Threading without locking Producer or Consumer -


tldr; version of main questions:

  1. while working threads, safe read list's contents 1 thread, while write it, long not delete list contents (reoganize order) , reads new object after new object added fully

  2. while int being updated "old value" "new value" 1 thread, there risk, if thread reads int value returned neither "old value" or "new value"

  3. is possible thread "skip" critical region if busy, instead of going sleep , wait regions release?

i have 2 pieces of code running in seperate threads , want have 1 act producer other. not want either thread "sleeping" while waiting access, instead skip forward in internal code if other thread accessing this.

my original plan share data via approach (and once counter got high enough switch secondary list avoid overflows).


pseudo code of flow original intended it.

producer { int counterproducer; bufferedobject newlyproducedobject; list <buffered_object> objectsproducer;     while(true)      {         <do stuff until new product created , added newlyproducedobject>;         objectsproducer.add(newlyproducedobject_object);         counterproducer++     } }   consumer { int counterconsumer; producer objectproducer; (contains reference producer class) list <buffered_object> personalqueue     while(true)         <do useful work, such working on personal queue, , polish nails if no personal queue>         //get outstanding requests , move personal queue         while (counterconsumer < objectproducer.getcounterproducer())         {             personalqueue.add(objectproducer.getitem(counterconsumer+1));             counterconsumer++;         } } 

looking @ this, looked fine @ first glance, knew not retrieving half constructed product queue, status of list regardless of should not problem if thread switch occour while producer adding new object. assumption correct, or can there problems here? (my guess consumer asking specific location in list , new objects added end, , objects never deleted not problem)

but caught eye was, similar problem occour "counterproducer" @ unknown value while being "counterproducer++"? result in value temporary "null" or unknown value? potential issue?

my goal have neither of 2 threads lock while waiting mutex instead continue loops, why made above first, there no locking.

if usage of list cause problems, workaround make linked list implementation, , share between 2 classes, still use counters see if new work has been added , keep last location while personalqueue moves new stuff personal queue. producer add new links, consumer reads them, , deletes previous. (no counter on list, external counters know how has been added , removed)


alternative pseudo code avoid counterconsumer++ risk (need this).

producer { int publiccounterproducer; int privatecounterproducer; bufferedobject newlyproducedobject; list <buffered_object> objectsproducer;     while(true)      {         <do stuff until new product created , added newlyproducedobject>;         objectsproducer.add(newlyproducedobject_object);         privatecounterproducer++         <need help: code updates publiccounterproducer privatecounterproducer if variable not   locked, else skips ahead, , counter updated @ next pass, @ point consumer must done reading stuff, ,   new stuff prepared already>           } }   consumer { int counterconsumer; producer objectproducer; (contains reference producer class) list <buffered_object> personalqueue     while(true)         <do useful work, such working on personal queue, , polish nails if no personal queue>         //get outstanding requests , move personal queue         <need help: tries read publicproducercounter , set readproducercounter this, else skips code>         while (counterconsumer < readproducercounter)         {             personalqueue.add(objectproducer.getitem(counterconsumer+1));             counterconsumer++;         } } 

so goal in 2nd part of code, , have not been able figure out how code this, make both classes not wait other in case other in "critical region" of updating publiccounterproducer. if read lock functionality correct, threads go sleep waiting release, not want. might end having use though, in case, first pseudocode it, , set "lock" on getting of value.

hope can me out many questions.

  1. no not safe. context switch can occur within .add after list has added object, before list has updated internal data structure.

  2. if int32, or if int64 , running in x64 process, there no risk. if have doubts, use interlocked class.

  3. yes, can use semaphore, , when time enter critical region, use waitone overload takes timeout. pass timeout of 0. if waitone returns true, acquired lock , can enter. if returns false, did not acquire lock , should not enter.

you should @ system.collections.concurrent namespace. in particular, @ blockingcollection. has bunch of try* operators can use add/remove items collection without blocking.


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -