.NET中的交叉过程读写同步Primation?
-
29-09-2019 - |
题
是否存在跨进程(类似于Mutex,但读/写独家锁定)的读/写锁定机制?我想允许并发读取访问,但独家写入访问。
解决方案
否。正如理查德(Richard)上面指出的那样,.net中没有这样的机制。这是使用互斥和信号量实现它的方法。
方法#1在 http://www.joecheng.com/blog/entries/writinganinter-processrea.html, ,引用:
// create or open global mutex
GlobalMutex mutex = new GlobalMutex("IdOfProtectedResource.Mutex");
// create or open global semaphore
int MoreThanMaxNumberOfReadersEver = 100;
GlobalSemaphore semaphore = new GlobalSemaphore("IdOfProtectedResource.Semaphore", MoreThanMaxNumberOfReadersEver);
public void AcquireReadLock()
{
mutex.Acquire();
semaphore.Acquire();
mutex.Release();
}
public void ReleaseReadLock()
{
semaphore.Release();
}
public void AcquireWriteLock()
{
mutex.Acquire();
for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
semaphore.Acquire(); // drain out all readers-in-progress
mutex.Release();
}
public void ReleaseWriteLock()
{
for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
semaphore.Release();
}
另一种选择是:
阅读锁定 - 如上所述。写下锁定如下(伪代码):
- Lock mutex
- Busy loop until the samaphore is not taken AT ALL:
-- wait, release.
-- Release returns value;
-- if value N-1 then break loop.
-- yield (give up CPU cycle) by using Sleep(1) or alternative
- Do write
- Release mutex
必须注意的是,更有效的方法是可能的,如下所示: http://en.wikipedia.org/wiki/readers-writers_problem #second_readers-writers_problem在上面的文章中查找“此解决方案是次优”的单词。
其他提示
Windows不包括跨进程读取器锁定锁。可以使用信号量和互斥品的组合来构造构造(静音者由作家持有独家访问权限或读者,然后使用信号量来释放其他读者 - IE作家只会等待互联网和读者等待) 。
但是,如果预期争论较低(即没有线程可长时间锁定),则相互排斥仍然可能更快:读者锁的额外复杂性淹没了允许多个读者进入的任何好处。只有在有更多读者和锁的时间内,锁才会更快,但是只有您的分析才能确认这一点。)
我已经根据Pavel的答案创建了此类。我尚未对其进行广泛的测试,但是我创建了一个简单的Winforms应用程序来测试它,到目前为止它运行良好。
请注意,它使用信号量,因此不支持重新输入。
public class CrossProcessReaderWriterLock
{
private readonly string _name;
const int _maxReaders = 10;
readonly Mutex _mutex;
readonly Semaphore _semaphore;
public CrossProcessReaderWriterLock(string name)
{
_name = name;
_mutex = new Mutex(false, name + ".Mutex");
_semaphore = new Semaphore(_maxReaders, _maxReaders, name + ".Semaphore");
}
public void AcquireReaderLock()
{
//Log.Info($"{_name} acquiring reader lock...");
_mutex .WaitOne();
_semaphore.WaitOne();
_mutex .ReleaseMutex();
//Log.Info($"{_name} reader lock acquired.");
}
public void ReleaseReaderLock()
{
_semaphore.Release();
//Log.Info($"{_name} reader lock released.");
}
public void AcquireWriterLock()
{
//Log.Info($"{_name} acquiring writer lock...");
_mutex.WaitOne();
for (int i = 0; i < _maxReaders; i++)
_semaphore.WaitOne(); // drain out all readers-in-progress
_mutex.ReleaseMutex();
//Log.Info($"{_name} writer lock acquired.");
}
public void ReleaseWriterLock()
{
for (int i = 0; i < _maxReaders; i++)
_semaphore.Release();
//Log.Info($"{_name} writer lock released.");
}
}
system.threading.mutex具有可用于程序内通信的静音。如果您想要它不支持的功能,则可以通过互斥X实现。
你看过吗 System.Threading.ReaderWriteLock
?这是 MSDN 关联。