是否有一个全局命名读/写锁?全局、有一个

2023-09-02 11:55:57 作者:浅夏淡过花开时

我服了一组文件的多个asp.net web应用程序。每隔一段时间,一会为它服务之前更新文件,但它无法更新文件,如果它是在使用中。

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?

推荐答案

它可以模拟使用互斥和信号量读取/写入器锁。我不会做,如果我有访问它每秒数千次,但是对于几十个或者上百次每秒,这应该只是罚款。

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.

此锁将允许1作家或由N个并发访问独占访问(可能很大,但你必须定义它)的读者。

This lock would allow exclusive access by 1 writer or concurrent access by N (possibly large, but you have to define it) readers.

下面是它的工作原理。我将使用10的读者作为一个例子。

Here's how it works. I'll use 10 readers as an example.

初​​始化命名的互斥体,最初unsignaled,并命名信号量有10个插槽:

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");

获取读锁:

// Lock access to the semaphore.
m.WaitOne();
// Wait for a semaphore slot.
s.WaitOne();
// Release mutex so others can access the semaphore.
m.ReleaseMutex();

发行读锁:

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.