Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a global named reader/writer lock?

Tags:

.net

locking

I have multiple asp.net web apps serving a set of files. Periodically, one will update the file before serving it, but it can't update the file if it is in use.

I could solve this issue by using a named mutex where the name is the file path (replacing the invalid characters of course). I've used this in other situations, but you can see how inefficient it is. Only one process will be able to serve the file at a time.

A reader/writer lock would be perfect, but they are designed to work within a single process. Plus I'd have to create a reader/writer lock for every file that might get updated, and there are a lot.

What I really need is a reader/writer lock that can be named like a mutex. Is there such a thing? Or can such a thing be created using the existing locks?

like image 770
Charles Avatar asked Mar 12 '09 19:03

Charles


People also ask

Which lock supports both read & write operation on lock?

An RW lock allows concurrent access for read-only operations, write operations require exclusive access.

What is read/write lock C++?

With C++14 came reader-writer locks. The idea is straightforward and promising. Arbitrary reading threads can access the critical region at the same time, but only one thread is allowed to write.

Which of the following classes are associated with Reader Writer locks?

The ReaderWriterLock class is used to synchronize access to a resource. At any given time, it allows concurrent read access to multiple (essentially unlimited) threads, or it allows write access for a single thread.

What is a reader/writer lock and when is it useful?

A readers/writer lock regulates access to a set of data. The readers/writer lock is so called because many threads can hold the lock simultaneously for reading, but only one thread can hold the lock for writing. Most device drivers do not use readers/writer locks.


2 Answers

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.

like image 127
Jim Mischel Avatar answered Sep 25 '22 08:09

Jim Mischel


How about this? Don't serve up files. Serve up copies of files. When you need to make a change, create a new file, and serve up a copy of that from then on.

like image 44
Matt Brunell Avatar answered Sep 24 '22 08:09

Matt Brunell