關於互斥鎖

来源:互联网 发布:网络开发技术 编辑:程序博客网 时间:2024/06/08 05:56

http://yy-programer.blogspot.tw/2012/07/blog-post.html

20110724046.jpg
由於最近使用Parallel for的平行化迴圈來運算

debug了一陣子都找不出問題所在

最後才知道遇上了critical section的問題


搜尋了一下C#提供了三種方法

Monitor,Mutex,和Semaphor
(可參閱此網誌的介紹)

其中最常見的方法就是Monitor的方法

而最簡易的方式就是使用lock指令
(lock就是實作Monitor的方法)

msdn lock方法

但lock卻有許多能力上的限制

看似簡單卻有許多小陷阱

可參考此網誌

介紹的蠻詳細的


在目前處理影像的部分由於Multi-Threading(多執行緒)跟非同步的關係

需要對同一個物件(影像)做存取

最簡單,又不會有問題的方式

就是自行宣告一個private 的物件作為lock的instance,如下:
(最好還是唯讀)

private Readonly Object _ThisLock = new Object();private Bitmap _Frame;...lock (this._ThisLock){//存取 _Frame 的 Critical code section.}...

如果有外部程式需要存取到此影像物件_Frame的話

就必須提供此物件的public的屬性讓外部程式參考使用
(通常不應該由外部程式來控制互斥鎖,應該在內部做掉)

public Bitmap Frame{    get    {        Bitmap bmp=null;        lock(this._ThisLock)        {           bmp=this._Frame.clone() as Bitmap;        }        return bmp;    }}

這樣就可以達到外部程式取得此物件時的安全性

但是內部程式每次在控制_Frame的時候都要寫一次lock實在很麻煩

所以可以將Frame加入set的功能

public Bitmap Frame{    get    {        Bitmap bmp=null;        lock(this._ThisLock)        {           bmp=this._Frame.clone() as Bitmap;        }        return bmp;    }    private set    {        lock(this._ThisLock)        {           if(this._Frame!=null) this._Frame.Dispose();           this._Frame=value;        }        }}
由於_Frame只可由內部做設定

所以使用private set的方式來處理

避免外部程式來設定_Frame

這樣以後內部程式在做_Frame存取時就直接使用Frame

既可達到封裝效果(其實只是偷懶...),又完成thread save的存取

當然這只是簡單的存取機制

如果需要對_Frame做比較複雜的存取

就還是要自己寫了互斥鎖了!!