c# - Fix-sized Concurrent list -


i have implemented simple task create fixed sized list allows concurrent writes , can dump latest snapshot of items in list @ time.

here implementation. offset increase atomically each thread , reset if reaches size of list. different threads should have isolated access each section of array.

my question when call dump(), first few items not stored in list. also, there interlocked function can both atomic increase , reset, don't have create locker object , lock block? thanks.

public static void main(string[] args) {                 concurrentcircularfixedlist<int> list = new concurrentcircularfixedlist<int>(20);     enumerable.range(1, 30).asparallel().select(nu => list.enqueu(nu)).tolist();     }  public class concurrentcircularfixedlist<t> {     private int _size;     private int _offset;     private sealed object _locker = new object();     privatet[] _list;      public concurrentcircularfixedlist(int size)     {         _size = size;         _offset = 0;         _list = new t[_size];     }      public int enqueu(t item)     {         _list[_offset] = item;         lock(_locker)         {             debug.write("b " + _offset);             _offset += 1;             if(_offset == _size)                 _offset = 0;             debug.write("a " + _offset + "\n");          }            return _offset;     }      public t[] dump()     {         return _list.toarray();     } } 

here's small version of lock-free list copies on write. performance characteristics should understood before using it. it's expensive when have many writers or list large. reads synchronization free since list immutable. improved in various ways of course idea. in effect sacrifices memory pressure , slower writes having 0 cost reads.

public class copywritelist<t> {     private volatile list<t> list;      public copywritelist()     {         list = new list<t>();     }      public copywritelist(int capacity)     {         list = new list<t>(capacity);     }      public t this[int index]     {         { return list[index]; }         set { replace(x => x[index] = value); }     }      public void clear()     {         replace(x => x.clear());     }      public void add(t item)     {         replace(x => x.add(item));     }      //etc....      private void replace(action<list<t>> action)     {         list<t> current;         list<t> updated;                 {             current = list;             updated = new list<t>(current);             action(updated);         } while (interlocked.compareexchange(ref list, updated, current) != current);     }      public list<t> getsnapshot()     {         return list;     } } 

alternatively here's fixed version of code. note there added contention between both readers , writers. performance suffer because of (like ever expensive context switching).

public class concurrentcircularfixedlist<t> {     private readonly int _size;     private int _offset;     private readonly object _locker = new object();     private readonly t[] _list;      public concurrentcircularfixedlist(int size)     {         _size = size;         _offset = 0;         _list = new t[_size];     }      public int enqueue(t item)     {         lock (_locker)         {             _list[_offset] = item;             debug.write("b " + _offset);             _offset += 1;             if (_offset == _size)                 _offset = 0;             debug.write("a " + _offset + "\n");             return _offset;         }     }      public t[] dump()     {         lock (_locker)             return _list.toarray();     } } 

Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -