It's possible to simulate a reader/writer lock using a Mutex and a Semaphore. I wouldn't do it if I had to access it thousands of times per second, but for dozens or perhaps hundreds of times per second, it should work just fine.
This lock would allow exclusive access by 1 writer or concurrent access by N (possibly large, but you have to define it) readers.
Here's how it works. I'll use 10 readers as an example.
Initialize a named Mutex, initially unsignaled, and a named Semaphore with 10 slots:
Mutex m = new Mutex(false, "MyMutex");
Semaphore s = new Semaphore(10, 10, "MySemaphore");
Acquire reader lock:
// Lock access to the semaphore.
m.WaitOne();
// Wait for a semaphore slot.
s.WaitOne();
// Release mutex so others can access the semaphore.
m.ReleaseMutex();
Release reader lock:
s.Release();
Acquire writer lock:
// Lock access to the seamphore
m.WaitOne();
// Here we're waiting for the semaphore to get full,
// meaning that there aren't any more readers accessing.
// The only way to get the count is to call Release.
// So we wait, then immediately release.
// Release returns the previous count.
// Since we know that access to the semaphore is locked
// (i.e. nobody can get a slot), we know that when count
// goes to 9 (one less than the total possible), all the readers
// are done.
s.WaitOne();
int count = s.Release();
while (count != 9)
{
// sleep briefly so other processes get a chance.
// You might want to tweak this value. Sleep(1) might be okay.
Thread.Sleep(10);
s.WaitOne();
count = s.Release();
}
// At this point, there are no more readers.
Release writer lock:
m.ReleaseMutex();
Although fragile (every process using this better have the same number for the semaphore count!), I think it will do what you want as long as you don't try to hit it too hard.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…