如果需要查看更多文章,請微信搜索公眾號 csharp編程大全,需要進C#交流群群請加微信z438679770,備注進群, 我邀請你進群! ! !

emaphore:可理解為允許執行緒執行信號的池子,池子中放入多少個信號就允許多少執行緒同時執行,
本文鏈接:
https://www.cnblogs.com/yifengjianbai/p/5468449.html
百度百科:Semaphore,是負責協調各個執行緒, 以保證它們能夠正確、合理的使用公共資源,也是作業系統中用于控制行程同步互斥的量,
Semaphore常用的方法有兩個WaitOne()和Release(),Release()的作用是退出信號量并回傳前一個計數,而WaitOne()則是阻止當前執行緒,直到當前執行緒的WaitHandle 收到信號,這里我舉一個例子讓大家更容易理解:當我們這樣實體化Semaphore時候
Semaphore sema = new Semaphore(x,y)有一隊人排隊上洗手間,人就相當于執行緒,x為還剩余的位置數量,y為總的位置數量,
WaitOne()方法就相當于人在等待洗手間位置的行為,而Release()方法就相當于一個人從洗手間出來的行為,這里再假設x和y都為5,說明開始的時候洗手間有5個空位置,且總共只有5個位置,當一隊超過5個人的隊伍要上洗手間的就排隊,首先WaitOne()方法等待,發現有空位就依次進去,每進去一個空位減一,直到進去5之后個沒有空位,這時候后面的人就一直等待,直到進去的人從洗手間出來Release()方法,空位加一,在等待WaitOne()方法的人發現有空位又進去一個空位減一……如此回圈往復,
請看下面例子:
public class Program { static Semaphore sema = new Semaphore(5, 5); const int cycleNum = 9; static void Main(string[] args) { for(int i = 0; i < cycleNum; i++) { Thread td = new Thread(new ParameterizedThreadStart(testFun)); td.Name = string.Format("編號{0}",i.ToString()); td.Start(td.Name); } Console.ReadKey(); } public static void testFun(object obj) { sema.WaitOne(); Console.WriteLine(obj.ToString() + "進洗手間:" + DateTime.Now.ToString()); Thread.Sleep(2000); Console.WriteLine(obj.ToString() + "出洗手間:" + DateTime.Now.ToString()); sema.Release(); } } 復制代碼
這里我要說明一點,信號量控制的只是執行緒同步的量,而不管順序,這個例子來說執行緒控制的就是執行緒同步量為5,也就是同時并發的執行緒數量為5個,至于是哪個先哪個后不是由這里的信號量決定的,
當然這個例子中因沒有做什么復雜的操作,一般情況進入執行緒的時間和每個執行緒要的時間不會有太大差別,所以執行的順序還是很規律的(為了說明這個問題我也是運行了多次才讓結果稍有不同,這里編號2搶在了編號1前面就是這個道理),如果執行緒中有很復雜的操作每個執行緒在運行中所用的時間有比較大的差別,或者回圈開始有復雜操作那么很可能就不是編號0先進入洗手間了,且不一定是先進入的就會先出來,
接下來再簡單介紹一下Semaphore的WaitOne()和Release()的多載方法
public int Release(int releaseCount);releaseCount指的是釋放的信號量數量,如果沒有引數默認為1,Release()就相當于Release(1)
這里要說明一點,當Release()或者Release(int releaseCount)執行時導致信號量計數大于最大數量時會拋出SemaphoreFullException例外,下面這種情況就會例外:
Semaphore sem = new Semaphore(4,5);
sem.Release(2);//這里是釋放2個信號量加上之前的4個,超出5個了
public virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne(int millisecondsTimeout);第一個多載引數timeout:指定時間間隔,若在這段時間內沒有接收到信號則跳過等待繼續執行
第二個多載引數millisecondsTimeout:指定時間間隔整數毫秒,若在這段時間內沒有接收到信號則跳過等待繼續執行
WaitOne()還有兩個多載方法不是很常用這里就不介紹了,上面的多載方法這里也不再進了案例說明了,有興趣的朋友可以自己嘗試一下,
說明:
1、如果semaphore.Release(n),n>semaphore最大容納信號量,將出例外,
2、當semaphore擁有的信號量為1時,Semaphore相當于Mutex
3、當semaphore擁有的信號量>1時,信號量的數量即可供多個執行緒同時獲取的個數,此時可認為獲取到信號量的執行緒將同時執行(實際情況可能與CPU核心數、CPU同時支出執行緒數有關)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/227011.html
標籤:.NET技术
上一篇:C# 代碼分兩個表單撰寫

