问题
My blocking ring queue don't use lock
or Mutex
, only two SemaphoreSlim
(block than 0 and than max element, so write and read part of array never intersects) and two int
indexes modified by Interlocked.Decrement
(not determine write/read index, but make it unique and correct move). There are no lock on index calculation and read/write element to array. I think it should work. Because, reference r/w is atomic, SemaphoreSlim
and Interlocked
make proper memory fence, SemaphoreSlim
separate read and write (read and write part of array newer cross).
But, what about processors' cache? I heard .Net guaranties cache coherence on any platforms. Is it right?
Should I read/write array element Thread.VolatuleRead
? Or System.Threading.Volatile.Read/Write ?
public class BlockingRingQueue<T> where T: class
{
const int BUFSIZE_LOG2 = 10;
const int BUFSIZE = 1 << BUFSIZE_LOG2; //
T[] buf = new T[BUFSIZE];
int start = 0;
int end = 0;
SemaphoreSlim canReadCount = new SemaphoreSlim(0);
SemaphoreSlim canWriteCount = new SemaphoreSlim(BUFSIZE);
public T Dequeue()
{
canReadCount.Wait();
int i = Interlocked.Decrement(ref end);
i = PositiveMod(i, BUFSIZE);
T val = buf[i];
canWriteCount.Release();
return val;
}
public void Enqueue(T val)
{
canWriteCount.Wait();
int i = Interlocked.Decrement(ref start);
i = PositiveMod(i, BUFSIZE);
buf[i] = val;
canReadCount.Release();
}
static int PositiveMod(int a, int b) => ((a % b) + b) % b;
}
来源:https://stackoverflow.com/questions/60348662/c-sharp-semaphoreslim-array-elements-read-write-synchronization