亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

詳細解析C#多線程同步事件及等待句柄

2020-01-24 00:57:05
字體:
來源:轉載
供稿:網友

最近搗鼓了一下多線程的同步問題,發現其實C#關于多線程同步事件處理還是很靈活,這里主要寫一下,自己測試的一些代碼,涉及到了AutoResetEvent 和 ManualResetEvent,當然還有也簡要提了一下System.Threading.WaitHandle.WaitOne 、System.Threading.WaitHandle.WaitAny和System.Threading.WaitHandle.WaitAll ,下面我們一最初學者的角度來看,多線程之間的同步。

假設有這樣的一個場景,主線程開了一個子線程,讓子線程等著,等主線程完成了某件事情時再通知子線程去往下執行,這里關鍵就在于這個怎讓子線程等著,主線程怎通知子線程,一般情況下我們不難想到用一個公共變量,于是咱們就有了下面的代碼:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class Class1   {     static bool flag = true;      static void DoWork()     {       Console.WriteLine("  worker thread started, now waiting on event...");       while (flag)       {        }       Console.WriteLine("  worker thread reactivated, now exiting...");     }      static void Main()     {       Console.WriteLine("main thread starting worker thread...");       Thread t = new Thread(DoWork);       t.Start();        Console.WriteLine("main thrad sleeping for 1 second...");       Thread.Sleep(1000);        Console.WriteLine("main thread signaling worker thread...");       flag = false;     }   } } 

雖然目的達到了,但是看著這代碼就糾結,下面該是我們的主角上場了,AutoResetEvent 和 ManualResetEvent,關于這兩者我們暫且認為是差不多了,稍后我會介紹他們的不同,這里以AutoResetEvent為例,其實很多官方的說法太過于抽象,這里通俗地講,可以認為AutoResetEvent就是一個公共的變量(盡管它是一個事件),創建的時候可以設置為false,然后在要等待的線程使用它的WaitOne方法,那么線程就一直會處于等待狀態,只有這個AutoResetEvent被別的線程使用了Set方法,也就是要發通知的線程使用了它的Set方法,那么等待的線程就會往下執行了,Set就是發信號,WaitOne是等待信號,只有發了信號,等待的才會執行。如果不發的話,WaitOne后面的程序就永遠不會執行。好下面看用AutoResetEvent改造上面的程序:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class Class2   {     static AutoResetEvent mEvent=new AutoResetEvent(false);     //static ManualResetEvent mEvent = new ManualResetEvent(false);      static void DoWork()     {       Console.WriteLine("  worker thread started, now waiting on event...");       mEvent.WaitOne();       Console.WriteLine("  worker thread reactivated, now exiting...");     }      static void Main()     {       Console.WriteLine("main thread starting worker thread...");       Thread t = new Thread(DoWork);       t.Start();        Console.WriteLine("main thrad sleeping for 1 second...");       Thread.Sleep(1000);        Console.WriteLine("main thread signaling worker thread...");       mEvent.Set();     }   } } 

這時代碼是不是清爽多了,這里其實你還會看到,把上面的AutoResetEvent換成ManualResetEvent也是沒有問題的,那么它兩之間的區別是什么呢?個人認為它們最大的區別在于,無論何時,只要 AutoResetEvent 激活線程,它的狀態將自動從終止變為非終止。相反,ManualResetEvent 允許它的終止狀態激活任意多個線程,只有當它的 Reset 方法被調用時才還原到非終止狀態。開下面的代碼:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class Class3   {     static AutoResetEvent mEvent = new AutoResetEvent(false);     //static ManualResetEvent mEvent = new ManualResetEvent(false);      static void DoWork()     {       Console.WriteLine("  worker thread started, now waiting on event...");       for (int i = 0; i < 3; i++)       {         mEvent.WaitOne();         //mEvent.Reset();         Console.WriteLine("  worker thread reactivated, now exiting...");       }     }      static void Main()     {       Console.WriteLine("main thread starting worker thread...");       Thread t = new Thread(DoWork);       t.Start();        for (int i = 0; i < 3; i++)       {         Thread.Sleep(1000);         Console.WriteLine("main thread signaling worker thread...");         mEvent.Set();       }     }   } } 

如果你想僅僅把AutoResetEvent換成ManualResetEvent的話,你發現輸出就會亂套了,為什么呢?

假如有autoevent.WaitOne()和manualevent.WaitOne(),當線程得到信號后都得以繼續執行。差別就在調用后,autoevent.WaitOne()每次只允許一個線程進入,當某個線程得到信號(也就是有其他線程調用了autoevent.Set()方法后)后,autoevent會自動又將信號置為不發送狀態,則其他調用WaitOne的線程只有繼續等待,也就是說,autoevent一次只喚醒一個線程。而manualevent則可以喚醒多個線程,當某個線程調用了set方法后,其他調用waitone的線程獲得信號得以繼續執行,而manualevent不會自動將信號置為不發送,也就是說,除非手工調用了manualevent.Reset()方法,否則manualevent將一直保持有信號狀態,manualevent也就可以同時喚醒多個線程繼續執行。

在上面代碼中,如果將AutoResetEvent換成ManualResetEvent的話,只要要在waitone后面做下reset,就會達到同樣的效果。

之后咱們再來個簡單的例子:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class Class4   {     public static AutoResetEvent mEvent = new AutoResetEvent(false);      public static void trmain()     {       Thread tr = Thread.CurrentThread;       Console.WriteLine("thread: waiting for an event");       mEvent.WaitOne();       Console.WriteLine("thread: got an event");       for (int x = 0; x < 10; x++)       {         Thread.Sleep(1000);         Console.WriteLine(tr.Name + ": " + x);       }     }     static void Main(string[] args)     {       Thread thrd1 = new Thread(new ThreadStart(trmain));       thrd1.Name = "thread1";       thrd1.Start();       for (int x = 0; x < 10; x++)       {         Thread.Sleep(900);         Console.WriteLine("Main:" + x);         if (5 == x) mEvent.Set();       }       while (thrd1.IsAlive)       {         Thread.Sleep(1000);         Console.WriteLine("Main: waiting for thread to stop");       }     }   } } 

是不是更有感覺了?之后咱來看看另外幾個東東:

System.Threading.WaitHandle.WaitOne 使線程一直等待,直到單個事件變為終止狀態;

System.Threading.WaitHandle.WaitAny 阻止線程,直到一個或多個指示的事件變為終止狀態;

System.Threading.WaitHandle.WaitAll 阻止線程,直到所有指示的事件都變為終止狀態。

然后再來個例子,以WaitAll使用為例:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class other   {     static void Main(string[] args)     {       Random randomGenerator = new Random();       AutoResetEvent[] resets=new AutoResetEvent[5];        for (int i = 0; i < 5; i++)       {         resets[i] = new AutoResetEvent(false);         int wTime = randomGenerator.Next(10)+1;          worker w = new worker(wTime, resets[i]);          Thread thrd1 = new Thread(new ThreadStart(w.work));         thrd1.Start();        }       WaitHandle.WaitAll(resets);       Console.WriteLine("ALL worker done - main exiting.");     }    }    public class worker   {     public string name;     public int wTime;     public AutoResetEvent mEvent;      public worker(int w, AutoResetEvent m)     {       name = w.ToString();       wTime = w * 1000;       mEvent = m;     }      public void work()     {       Console.WriteLine(name + " worker thread waiting for " + wTime + "....");       Thread.Sleep(wTime);       Console.WriteLine(name + " worker thread back...");       mEvent.Set();     }   } } 

簡單來說就是,開了5個線程,每個線程隨機休眠若干秒,都完成后通知主線程退出,這里就開了一個AutoResetEvent數組,主線程就WaitHandle.WaitAll(resets) ,子線程休眠完后就Set1個AutoResetEvent,最后都Set完后,主線程就會往下執行。最后最后再來個買書付款取貨的例子,加深理解:

using System; using System.Collections.Generic; using System.Text; using System.Threading;  namespace AutoResetEventTest {   class Program   {     const int numIterations = 10;     static AutoResetEvent myResetEvent = new AutoResetEvent(false);     static AutoResetEvent ChangeEvent = new AutoResetEvent(false);     //static ManualResetEvent myResetEvent = new ManualResetEvent(false);     //static ManualResetEvent ChangeEvent = new ManualResetEvent(false);     static int number; //這是關鍵資源      static void Main()     {       Thread payMoneyThread = new Thread(new ThreadStart(PayMoneyProc));       payMoneyThread.Name = "付錢線程";       Thread getBookThread = new Thread(new ThreadStart(GetBookProc));       getBookThread.Name = "取書線程";       payMoneyThread.Start();       getBookThread.Start();        for (int i = 1; i <= numIterations; i++)       {         Console.WriteLine("買書線程:數量{0}", i);         number = i;         //Signal that a value has been written.         myResetEvent.Set();         //ChangeEvent.Set();         Thread.Sleep(10);       }       payMoneyThread.Abort();       getBookThread.Abort();     }      static void PayMoneyProc()     {       while (true)       {         myResetEvent.WaitOne();         //myResetEvent.Reset();         Console.WriteLine("{0}:數量{1}", Thread.CurrentThread.Name, number);         ChangeEvent.Set();       }     }     static void GetBookProc()     {       while (true)       {         ChangeEvent.WaitOne();         //ChangeEvent.Reset();                 Console.WriteLine("{0}:數量{1}", Thread.CurrentThread.Name, number);         Console.WriteLine("------------------------------------------");         //Thread.Sleep(0);       }     }   } } 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九热视频这里只有精品| 久久久久久91| 亚洲国产一区二区三区四区| 亚洲精品国产拍免费91在线| 中日韩美女免费视频网站在线观看| 丝袜情趣国产精品| 国产精品高潮在线| 日韩欧美999| 国产有码一区二区| 91香蕉嫩草神马影院在线观看| 97人人模人人爽人人喊中文字| 亚洲国产成人av在线| 日韩视频精品在线| 亚洲人成电影网站色…| 国产精品女人久久久久久| 国产97在线观看| 亚洲精品国产成人| 136fldh精品导航福利| 亚洲成年网站在线观看| 日本一区二区不卡| 中文字幕日韩av电影| 亚洲国产精品久久精品怡红院| 中文字幕精品—区二区| 中文综合在线观看| 亚洲白虎美女被爆操| 欧美成人精品三级在线观看| 久久国产精品久久久| 成人情趣片在线观看免费| 久久久噜噜噜久噜久久| 日本精品免费一区二区三区| 一个人www欧美| 亚洲免费电影在线观看| 怡红院精品视频| 成人午夜小视频| 国产视频精品va久久久久久| 亚洲国产中文字幕久久网| 91久久久久久久久久久久久| 欧美高清视频在线观看| 狠狠操狠狠色综合网| 国产精品一二三在线| 国产精品美女呻吟| 欧美激情国内偷拍| 91在线国产电影| 超薄丝袜一区二区| 亚洲精品一区久久久久久| 久久久av亚洲男天堂| 国产黑人绿帽在线第一区| 欧美日韩精品在线视频| 欧美在线视频免费观看| 国产亚洲精品美女久久久久| 亚洲女人被黑人巨大进入al| 成人a视频在线观看| 亚洲精品国产精品自产a区红杏吧| 91产国在线观看动作片喷水| 久久伊人精品天天| 日韩精品中文字幕有码专区| 隔壁老王国产在线精品| 欧美午夜激情在线| 日韩美女中文字幕| 久久久久亚洲精品国产| 97超碰蝌蚪网人人做人人爽| 欧美黄色性视频| 中文字幕日韩综合av| 国产日韩欧美在线看| 性欧美暴力猛交69hd| 2021久久精品国产99国产精品| 日韩av在线看| 国模精品一区二区三区色天香| 亚洲精品色婷婷福利天堂| 欧美成人精品一区二区| 精品国产精品三级精品av网址| 日韩欧美亚洲国产一区| 日韩有码在线观看| 精品国产福利视频| 久久久久久久激情视频| 性日韩欧美在线视频| 国产精品视频午夜| 欧美超级乱淫片喷水| 在线看日韩av| 久久伊人精品一区二区三区| 亚洲精品美女在线观看| 97精品在线视频| 66m—66摸成人免费视频| 久久99久久久久久久噜噜| 精品国产一区二区三区久久狼黑人| 精品视频在线播放| www欧美xxxx| 国产精品美女av| 日本三级韩国三级久久| 欧美精品国产精品日韩精品| 青草青草久热精品视频在线观看| 国产精品99蜜臀久久不卡二区| 精品国产鲁一鲁一区二区张丽| 国产成人亚洲综合| 日韩在线播放av| 黑丝美女久久久| 自拍偷拍亚洲在线| 色悠悠久久久久| 国产精品jvid在线观看蜜臀| 久久久亚洲精品视频| 黑人巨大精品欧美一区二区免费| 一区二区欧美日韩视频| 最近的2019中文字幕免费一页| 国产精品三级网站| 日韩久久精品电影| 性欧美办公室18xxxxhd| 国产又爽又黄的激情精品视频| 国产精品一区二区久久久| 亚洲最大福利视频网站| 亚洲福利影片在线| 亚洲精品电影网站| 色综合天天综合网国产成人网| 在线观看免费高清视频97| 精品爽片免费看久久| 欧美精品久久久久久久免费观看| 91av国产在线| 色哟哟亚洲精品一区二区| 国产免费成人av| 亚洲国产福利在线| 另类专区欧美制服同性| 久久久久久综合网天天| 在线亚洲男人天堂| 欧美午夜片在线免费观看| 亚洲国产精品va在看黑人| 久久九九免费视频| 久久精品免费电影| 欧美激情奇米色| 久久久久久国产精品三级玉女聊斋| 国产69精品久久久久9999| 91亚洲精品一区二区| 91欧美精品午夜性色福利在线| 日韩专区在线播放| 欧美午夜宅男影院在线观看| 91精品久久久久久久久久久久久| 欧美性高跟鞋xxxxhd| 亚洲精品自拍视频| 国产ts人妖一区二区三区| 日韩视频永久免费观看| 国产日韩在线看片| 久久精品视频在线观看| 国产精品www网站| 成人性生交大片免费观看嘿嘿视频| 欧美猛交ⅹxxx乱大交视频| 中文字幕精品www乱入免费视频| 亚洲国产天堂久久综合| 国产精品对白刺激| 欧美日韩国产中文字幕| 亚洲福利在线看| 亚洲大胆人体视频| 欧美大全免费观看电视剧大泉洋| 欧美日韩激情小视频| 国产午夜精品一区二区三区| 国产一区二区激情| 91精品啪aⅴ在线观看国产| 日韩av电影中文字幕| 日韩精品一区二区三区第95| 欧美限制级电影在线观看| 国产精品96久久久久久| 久久香蕉国产线看观看网| 国产成人精品免高潮在线观看| 色偷偷av一区二区三区| 亚洲欧美制服丝袜| 国产精品一区久久久| 国产日韩综合一区二区性色av|