代码之家  ›  专栏  ›  技术社区  ›  Jeremy

NET中的跨进程读写同步?

  •  6
  • Jeremy  · 技术社区  · 14 年前

    是否有一种跨进程工作的读/写锁定机制(类似于互斥锁,但读/写是独占锁定)?我想允许并发读访问,但独占写访问。

    5 回复  |  直到 14 年前
        1
  •  5
  •   Pavel Radzivilovsky    12 年前

    不,正如Richard在上面提到的,在.NET中没有这种现成的机制。 这就是如何使用互斥锁和信号量来实现它。

    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#The_second_readers-writers_problem

        2
  •  5
  •   Pavel Radzivilovsky    12 年前

    Windows不包括跨进程读写器锁。可以使用信号量和互斥量的组合来构造互斥量(互斥量由写入程序持有以进行独占访问,或者由读取器持有,读取器随后使用信号量来释放其他读取器,即写入程序将仅等待互斥量和读取器来进行其中之一)。

    但是,如果争用率预期很低(即没有线程长时间持有锁),那么互斥可能会更快:读写器锁的额外复杂性压倒了允许多个读写器进入的任何好处(读写器锁只有在有更多读写器时才会更快,并且锁会保持很长时间,但只有您的分析才能确认这一点。)

        3
  •  1
  •   nightcoder    6 年前

    请注意,它使用信号量,因此不支持重入。

    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.");
        }
    }
    
        4
  •  -1
  •   McKay    14 年前

    System.Threading.Mutex 具有可用于进程内通信的互斥体。如果您想要它不支持的功能,可以通过互斥来实现。

        5
  •  -3
  •   AllenG    14 年前

    你看过吗 System.Threading.ReaderWriteLock ? 这是你的答案 MSDN