**程裡,如果需要共享資料,那麼一定需要使用同步技術,確保一次只有乙個執行緒訪問和改變共享資料的狀態。在.net中,lock語句、interlocked類和monitor類可用於程序內部的同步。
1、lock語句與執行緒安全
lock語句是設定鎖定和解除鎖定的一種簡單方式。在使用lock語句之前,先進入另乙個爭用條件。例如:
public class sharedstate
}public class job
public void dothejob()
}}static void main()
for (int i = 0; i < numtasks; i++)
conswww.cppcns.comole.writeline("summarized ", state.state);//預想應該輸出:summarized 1000000
}實際上的輸出與預想輸出並不一致,每次執行的輸出結果都不同,但沒有乙個是正確的。如果將執行緒數量減少,那麼得到正確值的次數會增多,但也不是每次都正確。
使用lock關鍵字,可以實現多個執行緒訪問同乙個數程式設計客棧據時的同步問題。lock語句表示www.cppcns.com等待指定物件的鎖定,該物件只能時引用型別。進行鎖定後——只鎖定了乙個執行緒,就執行lock語句塊中的**,在lock塊最後接觸鎖定,以便另乙個執行緒可以鎖定該物件。
lock(obj)
//鎖定靜態成員,可以所以其型別(object)
lock(typeof(staticcalss))
所以修改以上的**,使用syncroot模式。但是,如果是對屬性的訪問進行鎖定:
public class sharedstate
set
}}仍會出現前面的爭用情況。在方法呼叫get儲存器,以獲得state的當前值,然後set儲存器給state設定新值。在呼叫物件的get和set儲存器期間,物件並沒有鎖定,另乙個執行緒仍然可以獲得臨時值。最好的方法是在不改變sharedstate類的前提下,在呼叫方法中,將lock語句新增到合適的地方:
public class sharedstate
}public class job
public void dothejob()}}}
在乙個地方使用lock語句並不意味著訪問物件的其他執行緒都在等待。必須對每個訪問共享資料的執行緒顯示使用同步功能。
為使對state的修改作為乙個原子操作,修改**:
public class sharedstate
} public int incrementstate()
}}//外部訪問
public void dothejob()
}2、interlocked類
interlocked類用於使變數的簡單語句原子化。i++並非執行緒安全的,它涉及三個步驟:取值、自增、存值。這些操作可能被執行緒排程器打斷。interlocked類提供了以執行緒安全的方式遞增、遞減、交換和讀取值的方法。interlocked類只能用於簡單的同步問題,而且很快。因此,上面的incrementstate()方法的**可以改為:return interlocked.increment(ref state);
3、monitor類
lcok語句最終會有c#編譯器解析為使用monitor類。
lock(obj)
簡單的lock(obj)語句會被解析為呼叫enter()方法,該方法會一直等待,直到執行緒鎖定物件。一次只有乙個執行緒能鎖定物件,只要解除鎖定,執行緒就可以進入同步階段。monitor類的exit()方法解除鎖定。編譯器把exit()方法放在try塊的finally中,不論是否丟擲異常,都將在語句塊執行末尾解除鎖定。
monitor.enter(obj);
tryfinally
相對於lock語句,mpnitor類可以設定乙個等待被鎖定的超時值。這樣就不會無限期的等待鎖定,如果等待鎖定時間超過規定時間,則返回false,表示未被鎖定,執行緒不再等待,執行其他操作。也許以後,該執行緒會再次嘗試獲得鎖定:
bool locktaken = false;
monitor.tryenter(obj,500, ref locktaken);//在500ms內,是否鎖定了物件
if (locktaken)
finally }
else
如果基於物件的鎖定物件(monitor)的系統開銷由於垃圾**而過高,可以使用spinlock結構。,spinlock結構適用於:有大量的鎖定,而且鎖定時間總是非常短的情況。應避免使用多個spinlock結構,也不要呼叫任何可能阻塞的內容。
程序的同步
解決多個程序同時訪問同乙個資源的時候出現資料破壞的問題 首先找到臨界區 臨界區 一段 對共享的資料進行訪問 然後對臨界區進行保護 加鎖 應該滿足三個條件 硬體方法有以上兩種,下面僅介紹第一種,這種操作是基於硬體的原子指令 執行過程中不能被中斷 實現的。testandset 就是原子操作 臨界區要設定...
程序 執行緒的同步
int pthread mutex init pthread mutex t restrict mutex,const pthread mutexattr t restrict arr int pthread mutex destroy pthread mutex t mutex int pthre...
程序的同步(中)
包含程序同步關係,互斥關係 一.硬體同步機制 二.訊號量機制 1.整形訊號量 基礎,因為有缺點所以轉為記錄性訊號量 2.記錄型訊號量 重要 3.and型訊號量 會用,等待資源多時用 4.訊號量集 了解 三.管程機制 11.1 訊號量s int s 只可以在初始化時賦值和p,v操作時改值 初始值是非負...