简体   繁体   English

.NET中的跨进程读写同步至关重要?

[英]Cross-process read-write synchronization primative in .NET?

Is there a read/write locking mechanism that works across processes (similar to Mutex, but read/write instead exclusive locking)? 是否存在跨进程工作的读/写锁定机制(类似于Mutex,但是读/写而不是独占锁定)? I would like to allow concurrent read access, but exclusive write access. 我想允许并发读访问,但独占写访问。

No. As Richard noted above, there is no such out of the box mechanism in .NET. 没有。正如理查德在上面提到的那样,.NET中没有这种开箱即用的机制。 This is how to implement it using a mutex and a semaphore. 这是使用互斥锁和信号量实现它的方法。

Method #1 is described in http://www.joecheng.com/blog/entries/Writinganinter-processRea.html , quoting: 方法#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();
}

An alternative would be: 另一种选择是:

Read locking - as above. 读锁定 - 如上所述。 Write locking as follows (pseudocode): 写锁定如下(伪代码):

- 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

It must be noted that more efficient approach is possible, as here: http://en.wikipedia.org/wiki/Readers-writers_problem#The_second_readers-writers_problem Look for the words "This solution is suboptimal" in the article above. 必须注意的是,更有效的方法是可行的,如下所示: http//en.wikipedia.org/wiki/Readers-writers_problem#The_second_readers-writers_problem在上面的文章中查找“此解决方案不是最理想的”。

Windows does not include a cross process Reader-Writer lock. Windows不包含跨进程Reader-Writer锁。 A combination of Semaphore and Mutex could be used to construct ones (the Mutex is held by a writer for exclusive access or by a Reader which then uses the Semaphore to release other readers—ie writers would wait on just the mutex and readers for either). 可以使用Semaphore和Mutex的组合来构造一个(Mutex由作者独立访问或由读者持有,然后读者使用Semaphore释放其他读者 - 即编写者将等待互斥和读者) 。

However, if contention is expected to be low (ie no thread holds a lock for long) then mutual exclusion may still be faster: the additional complexity of the reader-writer lock overwhelms any benefit of allowing multiple readers in. (A reader-writer lock will only be faster if there are many more readers and locks are held for significant time—but only your profiling can confirm this.) 但是,如果预期争用率很低(即没有线程长时间持有锁),那么互斥可能仍然会更快:读写器锁的额外复杂性压倒了允许多个读者进入的任何好处。(读写器)如果有更多的读者和锁定持续很长时间,锁定只会更快 - 但只有你的分析可以确认这一点。)

I've created this class based on Pavel's answer. 我根据Pavel的答案创建了这个类。 I haven't tested it extensively yet, but I've created a simple winforms application to test it and so far it works well. 我还没有广泛测试它,但我已经创建了一个简单的winforms应用程序来测试它,到目前为止它运行良好。

Please note, that it uses a semaphore, so it doesn't support reentrancy. 请注意,它使用信号量,因此它不支持重入。

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 has a mutex that can be used for intra-process communication. System.Threading.Mutex有一个可用于进程内通信的互斥锁。 If you would like functionality that it doesn't support, it can be implemented via a mutex. 如果您想要它不支持的功能,可以通过互斥锁实现。

Have you looked at System.Threading.ReaderWriteLock ? 你看过System.Threading.ReaderWriteLock吗? Here's the MSDN Link. 这是MSDN链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM