如何使用互斥锁

我有一个线程,即通过tcp发送存储在List 类型的缓冲区中的数据。 另一个线程是写入缓冲区。 因为我对c#不是很熟悉,所以我想知道如何正确使用锁或Mutex。

这是我最终想要使用的代码:

while(buffer.isLocked()) { buffer.wait(); } buffer.lockBuffer(); buffer.add(tcpPacket); buffer.unlockBuffer(); buffer.notify(); 

这是我目前的代码。 我希望有人可以帮助我完成它。

 public class Buffer { private Mutex mutex; private List buffer; private bool locked = false; public Buffer() { mutex = new Mutex(false); buffer = new List(); } public bool isLocked() { return locked; } public void lockBuffer() { if (!locked) { //... locked = true; } } public void unlockBuffer() { if(locked) { mutex.ReleaseMutex(); locked = false; } } public void wait() { mutex.WaitOne(); } public void notify() { //... } } 

如果使用System.Collections.Concurrent.BlockingCollection会更好。 它不需要外部同步。

对于那些不使用4.0的人

 using System; using System.Collections.Generic; using System.Threading; namespace MyCollections { public class BlockingQueue : IDisposable { Queue _Queue = new Queue(); SemaphoreSlim _ItemsInQueue = null; SemaphoreSlim _FreeSlots = null; int _MaxItems = -1; public BlockingQueue(int maxItems=Int32.MaxValue) { _MaxItems = maxItems; _ItemsInQueue = new SemaphoreSlim(0, maxItems); _FreeSlots = new SemaphoreSlim(maxItems, maxItems); } public void Dispose() { if (_ItemsInQueue != null) _ItemsInQueue.Dispose(); if (_FreeSlots != null) _FreeSlots.Dispose(); } public int Count { get { return _ItemsInQueue.CurrentCount; } } public void Add(T item) { if(_MaxItems != Int32.MaxValue) _FreeSlots.Wait(); lock (this) { _Queue.Enqueue(item); _ItemsInQueue.Release(); } } public T Take() { T item = default(T); _ItemsInQueue.Wait(); lock (this) { item = _Queue.Dequeue(); if (_MaxItems != Int32.MaxValue) _FreeSlots.Release(); } return item; } } } 

以下代码不是线程安全的。 如果两个线程同时进入此方法,则两个线程都可以成功传递if条件。

 public void lockBuffer() { if (!locked) { //... locked = true; } } 

你可能只想做这样的事情:

 lock (_sycnObject) { buffer.lockBuffer(); buffer.add(tcpPacket); buffer.unlockBuffer(); buffer.notify(); } 

我不认为你正在做一些复杂的事情,它需要的不仅仅是简单易用的锁语句。

我不会使用互斥锁,因为我认为你没有处理多个进程同步。 锁定很简单,实现起来很简单:

 class Buffer { private readonly object syncObject = new object(); private readonly List buffer = new List(); public void AddPacket(string packet) { lock (syncObject) { buffer.Add(packet); } } public void Notify() { // Do something, if needed lock again here // lock (syncObject) // { // Notify Implementation // } } } 

用法很明显(按照您的要求):

 var myBuffer = new Buffer(); myBuffer.Add("Hello, World!"); myBuffer.Notify();