線程也瘋狂-----線程同步(2)

內核模式構造

前篇咱們已經提過,內核模式構造比用戶模式構造慢不少,一個緣由是它們要求Windows操做系統自身的配合,另外一個緣由是內核對象上調用的每一個方法都形成調用線程從託管代碼轉換爲本機用戶模式代碼,再轉換爲背景內核模式代碼,這些轉換須要大量的CPU時間。面試

可是內核模式擁有用戶模式沒有的優勢:windows

1. 當檢測到資源競爭時,windows會阻塞輸掉的線程併發

2. 可同步一臺機器中不一樣進程中運行的線程spa

3. 防止未經受權的帳戶訪問線程操作系統

4. 阻塞的線程能夠指定超時值線程

事件和信號量就是兩種內核模式線程同步構造。code

WaitHandle抽象基類,惟一的做用就是包裝一個windows內核對象句柄,繼承WaitHadle的對象能夠分爲三類:1. 事件構造(AutoResetEvent、ManualResetEvent) 2. Semaphore構造 3. Mutex構造對象

事件構造

AutoResetEvent、ManualResetEvent:其基本工做原理是多個線程持有同一個XXXResetEvent,在這個XXXResetEvent未被set前,各線程都在WaitOne()除掛起;在這個XXXResetEvent被set後,全部被掛起的線程中有一個(AutoResetEvent的狀況下)或所有(ManualResetEvent的狀況下)恢復執行。blog

 

AutoResetEvent舉例:繼承

 1  AutoResetEvent autoResetEvent = new AutoResetEvent(true); //true默認執行第一個未掛起的線程
 2 
 3             Task.Factory.StartNew(() =>
 4             {
 5                 Console.WriteLine("線程1:我已經開始任務已經執行,等待指示");
 6                 autoResetEvent.WaitOne();
 7                 Console.WriteLine("線程1任務執行結束");
 8                 autoResetEvent.Set();
 9             });
10 
11 
12             Task.Factory.StartNew(() =>
13             {
14                 Console.WriteLine("線程2:我已經開始任務已經執行,等待指示");
15                // Thread.Sleep(1000);
16                 autoResetEvent.WaitOne();
17                 Console.WriteLine("線程2任務執行結束");;
18             });
19             Console.WriteLine("程序結束");
20             Console.ReadLine();

 

ManualResetEvent舉例:

 1  ManualResetEvent autoResetEvent = new ManualResetEvent(false); //true默認執行第一個未掛起的線程
 2 
 3             Task.Factory.StartNew(() =>
 4             {
 5                 Console.WriteLine("線程1:我已經開始任務已經執行,等待指示");
 6                 autoResetEvent.WaitOne();
 7                 Console.WriteLine("線程1任務執行結束");
 8 
 9             });
10             Task.Factory.StartNew(() =>
11             {
12                 Console.WriteLine("線程2:我已經開始任務已經執行,等待指示");
13                // Thread.Sleep(1000);
14                 autoResetEvent.WaitOne();
15                 Console.WriteLine("線程2任務執行結束");;
16             });
17             Console.WriteLine("1s後再通知線程執行任務");
18             Thread.Sleep(1000);
19             autoResetEvent.Set();
20             Console.WriteLine("程序結束");
21             Console.ReadLine();

記得有一個面試題,建立四個線程而且按照順序打印ABCD重複三次,就考得是線程同步的問題,你們能夠思考一下怎麼解決。

 

Semaphore構造

構造原理:經過內核維護int32變量,信號量爲0時,在信號量上等待的線程會阻塞,信號量大於0時,解除阻塞,在信號量上等待的線程接觸阻塞時,內核自動從信號量的計數中減1.

 

 1   Semaphore semaphore = new Semaphore(0, Int32.MaxValue); //指定最大併發
 2 
 3             Task.Factory.StartNew(() =>
 4             {
 5                 Console.WriteLine("線程1:我已經開始任務已經執行,等待指示");
 6                 semaphore.WaitOne();
 7                 Console.WriteLine("線程1任務執行結束");
 8                 semaphore.Release();
 9 
10             });
11             Task.Factory.StartNew(() =>
12             {
13                 Console.WriteLine("線程2:我已經開始任務已經執行,等待指示");
14                // Thread.Sleep(1000);
15                 semaphore.WaitOne();
16                 Console.WriteLine("線程2任務執行結束");;
17             });
18             Console.WriteLine("1s後再通知線程執行任務");
19             semaphore.Release();
20             Console.WriteLine("程序結束");
21             Console.ReadLine();

 

Mutex構造

原理同AtuoResetEvent類似,都是一次只能釋放一個正在等待的線程,可是互斥有一些額外的邏輯,這使得它比先前的構造更復雜。首先,Mutex對象會查詢調用線程的Int32 ID,記錄是哪個線程得到了它,一個線程調用ReleaseMutex時,mutex確保調用線程就是獲取Mutex的那個線程,否則mutex對象的狀態就會發生改變,另外,Mutex對象維護着一個遞歸計數,指出擁有該Mutex的線程擁有了它多少次,若是一個線程當前擁有一個mutex,然後該線程再次在mutex上等待,計數就會遞增,這個線程容許繼續運行。

構造Mutex的遞歸鎖:

 1 class MutexLock : IDisposable
 2     {
 3          private readonly Mutex mutex;
 4 
 5          public MutexLock()
 6         {
 7             mutex = new Mutex();
 8         }
 9 
10         public void Enter()
11         {
12             mutex.WaitOne();
13             //隨便坐任何事情
14             Leave();
15             mutex.ReleaseMutex();
16 
17         }
18 
19         public void Leave()
20         {
21             mutex.WaitOne();
22             //隨便坐任何事情
23             mutex.ReleaseMutex();
24         }
25 
26         public void Dispose()
27         {
28             mutex.Dispose();
29         }
30     }
相關文章
相關標籤/搜索