Dot-Net

是否有全域命名的讀/寫鎖?

  • August 17, 2017

我有多個提供一組文件的 asp.net Web 應用程序。定期地,在提供文件之前會更新文件,但如果文件正在使用中,則無法更新文件。

我可以通過使用名稱為文件路徑的命名互斥鎖來解決此問題(當然要替換無效字元)。我在其他情況下使用過它,但你可以看到它的效率是多麼低。一次只有一個程序能夠提供文件。

讀/寫鎖是完美的,但它們被設計為在單個程序中工作。另外,我必須為每個可能會更新的文件創建一個讀/寫鎖,而且還有很多。

我真正需要的是一個可以像互斥鎖一樣命名的讀/寫鎖。有這樣的事嗎?或者可以使用現有的鎖創建這樣的東西嗎?

可以使用 Mutex 和 Semaphore 模擬讀取器/寫入器鎖。如果我必須每秒訪問它數千次,我不會這樣做,但是每秒數十次甚至數百次,它應該可以正常工作。

此鎖將允許 1 個寫入者獨占訪問或 N 個(可能很大,但您必須定義它)讀取者並發訪問。

這是它的工作原理。我將以 10 個讀者為例。

初始化一個命名的 Mutex,最初是無信號的,以及一個有 10 個槽的命名信號量:

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

獲取寫入器鎖:

// 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.

釋放寫入者鎖:

m.ReleaseMutex();

雖然很脆弱(使用這個更好的每個程序都有相同的信號量計數!),我認為只要你不試圖太用力地打擊它,它就會做你想做的事。

引用自:https://stackoverflow.com/questions/640122