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

首頁 > 編程 > C# > 正文

C# 線程同步詳解

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

前言

當線程池的線程阻塞時,線程池會創建額外的線程,而創建、銷毀和調度線程所需要相當昂貴的內存資源,另外,很多的開發人員看見自己程序的線程沒有做任何有用的事情時習慣創建更多的線程,為了構建可伸縮、響應靈敏的程序,我們在前面介紹了C#異步編程詳解

但是異步編程同樣也存在著很嚴重的問題,如果兩個不同的線程訪問相同的變量和數據,按照我們異步函數的實現方式,不可能存在兩個線程同時訪問相同的數據,這個時候我們就需要線程同步。多個線程同時訪問共享數據的時,線程同步能防止數據損壞,之所以強調同時這個概念,因為線程同步本質就是計時問題。

異步和同步是相對的,同步就是順序執行,執行完一個再執行下一個,需要等待、協調運行。異步就是彼此獨立,在等待某事件的過程中繼續做自己的事,不需要等待這一事件完成后再工作。線程就是實現異步的一個方式。異步是讓調用方法的主線程不需要同步等待另一線程的完成,從而可以讓主線程干其它的事情。

基元用戶模式和內核模式構造

基礎概念

基元:可以在代碼中使用的簡單的構造

用戶模式:通過特殊的CPU指令協調線程,操作系統永遠檢測不到一個線程在基元用戶模式的構造上阻塞。

內核模式:由windows自身提供,在應用程序的線程中調用由內核實現的函數。

用戶模式構造

易變構造

C#編譯器、JIT編譯器和CPU都會對代碼進行優化,它們盡量保證保留我們的意圖,但是從多線程的角度出發,我們的意圖并不一定會得到保留,下面舉例說明:

 static void Main(string[] args) { Console.WriteLine("讓worker函數運行5s后停止"); var t = new Thread(Worker); t.Start(); Thread.Sleep(5000); stop = true; Console.ReadLine(); } private static bool stop = false; private static void Worker(object obj) { int x = 0; while (!stop) { x++; } Console.WriteLine("worker函數停止x={0}",x); }
 

編譯器如果檢查到stop為false,就生成代碼來進入一個無限循環,并在循環中一直遞增x,所以優化循環很快完成,但是編譯器只檢測stop一次,并不是每次都會檢測。

例子2---兩個線程同時訪問:

class test { private static int m_flag = 0; private static int m_value = 0; public static void Thread1(object obj) { m_value = 5; m_flag = 1; } public static void Thread2(object obj) { if (m_flag == 1) Console.WriteLine("m_value = {0}", m_value); } //多核CPU機器才會出現線程同步問題 public void Exec() { var thread1 = new Thread(Thread1); var thread2 = new Thread(Thread2); thread1.Start(); thread2.Start(); Console.ReadLine(); } }

程序在執行的時候,編譯器必須將變量m_flag和m_value從RAM讀入CPU寄存器,RAM先傳遞m_value的值0,thread1把值變為5,但是thread2并不知道thread2仍然認為值為0,這種問題一般來說發生在多核CPU的概率大一些,應該CPU越多,多個線程同時訪問資源的幾率就越大。

關鍵字volatile,作用禁止C#編譯器、JTP編譯器和CPU執行的一些優化,如果做用于變量后,將不允許字段緩存到CPU的寄存器中,確保字段的讀寫都在RAM中進行。

互鎖構造

System.Threading.Interlocked類中的每個方法都執行一次原子的讀取以及寫入操作,調用某個Interlocked方法之前的任何變量寫入都在這個Interlocked方法調用之前執行,而調用之后的任何變量讀取都在這個調用之后讀取。

Interlocked方法主要是對INT32變量進行靜態操作Add、Decrement、Compare、Exchange、CompareChange等方法,也接受object、Double等類型的參數。

原子操作:是指不會被線程調度機制打斷的操作;這種操作一旦開始,就一直運行到結束,中間不會有任何 context switch (切換到另一個線程)。

代碼演示:

說明:通過Interlocked的方法異步查詢幾個web服務器,并同時返回數據,且結果只執行一次。

//上報狀態類型 enum CoordinationStatus { Cancel, Timeout, AllDone }
class AsyncCoordinator { //AllBegun 內部調用JustEnded來遞減它 private int _mOpCount = 1; //0=false,1=true private int _mStatusReported = 0; private Action<CoordinationStatus> _mCallback; private Timer _mTimer; //發起一個操作之前調用 public void AboutToBegin(int opsToAdd = 1) { Interlocked.Add(ref _mOpCount, opsToAdd); } //處理好一個操作的結果之后調用 public void JustEnded() { if (Interlocked.Decrement(ref _mOpCount) == 0) { ReportStatus(CoordinationStatus.AllDone); }  } //該方法必須在發起所有操作后調用 public void AllBegin(Action<CoordinationStatus> callback, int timeout = Timeout.Infinite) { _mCallback = callback; if (timeout != Timeout.Infinite) { _mTimer = new Timer(TimeExpired, null, timeout, Timeout.Infinite); JustEnded(); } } private void TimeExpired(object o) { ReportStatus(CoordinationStatus.Timeout); } public void Cancel() { ReportStatus(CoordinationStatus.Cancel); } private void ReportStatus(CoordinationStatus status) { //如果狀態從未報告過,就報告它,否則就忽略它,只調用一次 if (Interlocked.Exchange(ref _mStatusReported, 1) == 0) { _mCallback(status); }  } }
class MultiWebRequest { //輔助類 用于協調所有的異步操作 private AsyncCoordinator _mac = new AsyncCoordinator(); protected Dictionary<string,object> _mServers = new Dictionary<string, object> { {"http://www.baidu.com",null},{"http://www.Microsoft.com",null},{"http://www.cctv.com",null}, {"http://www.souhu.com",null},{"http://www.sina.com",null},{"http://www.tencent.com",null}, {"http://www.youku.com",null} }; private Stopwatch sp; public MultiWebRequest(int timeout = Timeout.Infinite) { sp = new Stopwatch(); sp.Start(); //通過異步方式一次性發起請求 var httpclient = new HttpClient(); foreach (var server in _mServers.Keys) { _mac.AboutToBegin(1); httpclient.GetByteArrayAsync(server).ContinueWith(task => ComputeResult(server, task)); } _mac.AllBegin(AllDone,timeout); Console.WriteLine(""); } private void ComputeResult(string server, Task<Byte[]> task) { object result; if (task.Exception != null) { result = task.Exception.InnerException; } else { //線程池處理IO result = task.Result.Length; } //保存返回結果的長度 _mServers[server] = result; _mac.JustEnded(); } public void Cancel() { _mac.Cancel(); } private void AllDone(CoordinationStatus status) { sp.Stop(); Console.WriteLine("響應耗時總計{0}",sp.Elapsed); switch (status) { case CoordinationStatus.Cancel:  Console.WriteLine("操作取消");  break; case CoordinationStatus.AllDone:  Console.WriteLine("操作完成,完成的結果如下");  foreach (var server in _mServers)  {  Console.WriteLine("{0}",server.Key);  object result = server.Value;  if (result is Exception)  {  Console.WriteLine("錯誤原因{0}",result.GetType().Name);  }  else  {  Console.WriteLine("返回字節數為:{0}",result);  }  }  break; case CoordinationStatus.Timeout:  Console.WriteLine("操作超時");  break; default:  throw new ArgumentOutOfRangeException("status", status, null); } } }

非常建議大家參考一下以上代碼,我在對服務器進行訪問時,也會常常參考這個模型。

簡單的自旋鎖

class SomeResource { private SimpleSpinLock s1 = new SimpleSpinLock(); public void AccessResource() { s1.Enter(); //一次是有一個線程才能進入訪問 s1.Leave(); } } class SimpleSpinLock { private int _mResourceInUse; public void Enter() { while (true) { if(Interlocked.Exchange(ref _mResourceInUse,1)==0)  return; } } public void Leave() { Volatile.Write(ref _mResourceInUse,1); } }

這就是一個線程同步鎖的簡單實現,這種鎖的最大問題在于,存在競爭的情況下會造成線程的“自旋”,這會浪費CPU的寶貴時間,組織CPU做更多的工作,因此,這種自旋鎖應該用于保護那些執行的非??斓拇a。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲综合视频1区| 国产v综合v亚洲欧美久久| 欧美国产日产韩国视频| 欧美大片在线影院| 久久亚洲国产精品| 欧美美女操人视频| 日韩av电影在线网| 丝袜亚洲另类欧美重口| 国产亚洲精品美女久久久| 亚洲国产97在线精品一区| 奇米影视亚洲狠狠色| 午夜免费久久久久| 久久久久久国产免费| 欧美天堂在线观看| 欧美大尺度在线观看| 欧美劲爆第一页| 亚洲xxxx在线| 亚洲成人网久久久| 尤物yw午夜国产精品视频| 精品美女久久久久久免费| 人妖精品videosex性欧美| 久久久久久久色| 日本一区二区三区在线播放| 亚洲视频第一页| 91av在线免费观看| 日韩资源在线观看| 97av在线视频免费播放| 午夜精品视频网站| 精品日本美女福利在线观看| 中文字幕久久久av一区| 欧美三级欧美成人高清www| xxxxxxxxx欧美| 亚洲成人在线网| 中文字幕久久久av一区| 最新日韩中文字幕| 久久综合久久88| 亚洲欧美在线免费观看| 欧美不卡视频一区发布| 亚洲国产精品久久久久秋霞不卡| 国产精品一区二区3区| 亚洲一区二区中文字幕| 日韩有码在线电影| 国产精品香蕉av| 精品福利视频导航| 久久亚洲国产精品| 欧美精品福利在线| 久久亚洲精品网站| 日韩电影免费观看中文字幕| 日韩在线视频二区| 亚洲图片欧洲图片av| 国产精品日韩在线一区| 欧美一级bbbbb性bbbb喷潮片| 中日韩美女免费视频网站在线观看| 视频在线观看99| 成人亚洲综合色就1024| 尤物九九久久国产精品的分类| 成人免费观看网址| 国产精品丝袜久久久久久不卡| 国模叶桐国产精品一区| 国产z一区二区三区| 国产啪精品视频| 午夜免费久久久久| 欧洲精品久久久| 亚洲精品有码在线| 91久久在线观看| 91精品国产色综合久久不卡98| 中文字幕日本精品| 亚洲综合自拍一区| 欧美精品激情视频| 国产精品久久久久久婷婷天堂| 欧美电影免费看| 成人在线激情视频| 久久精品色欧美aⅴ一区二区| 亚洲97在线观看| 91精品在线观| 97久久精品人人澡人人爽缅北| 日韩av日韩在线观看| 在线视频欧美日韩| 欧美整片在线观看| 亚洲欧美一区二区三区情侣bbw| 久久成人一区二区| 夜色77av精品影院| 亚洲高清福利视频| 91在线观看免费| 欧美乱妇40p| 韩国一区二区电影| 日韩电影中文字幕| 成人国产精品一区| 日韩精品电影网| 亚洲欧美制服另类日韩| 欧美电影电视剧在线观看| 亚洲精品视频免费在线观看| 国产成人avxxxxx在线看| 国产国产精品人在线视| 国产精品白嫩初高中害羞小美女| 欧美性高潮在线| 久久不射电影网| 中文字幕日韩av综合精品| 国产精品久久久久久久久久久久| 在线免费观看羞羞视频一区二区| 日韩高清电影免费观看完整版| 亚洲第一天堂av| 亚洲黄在线观看| 国产欧美久久久久久| 欧美激情国产高清| 亚洲天堂成人在线| 久久精品国产亚洲精品2020| 欧美性色19p| 欧美日韩精品二区| 国产精品视频午夜| 欧美一区二区三区免费观看| 97久久精品人人澡人人爽缅北| 日韩视频免费观看| 欧美美女操人视频| 日本精品久久久| 欧美一级成年大片在线观看| 亚洲伊人久久大香线蕉av| 中文字幕日韩在线观看| 久久夜色精品亚洲噜噜国产mv| 亚洲第一天堂无码专区| 日韩福利伦理影院免费| 成人黄色午夜影院| 91亚洲精品一区二区| 欧美成人精品影院| 亚洲精品欧美日韩专区| 深夜福利亚洲导航| 亚洲精品久久久久中文字幕欢迎你| 日韩成人激情影院| 性色av一区二区咪爱| 欧美国产日韩免费| 韩国19禁主播vip福利视频| 国产精品日韩在线| 欧美一区二粉嫩精品国产一线天| 亚洲一区二区三区四区在线播放| 一区二区三区无码高清视频| 欧美日韩成人黄色| 亚洲免费电影在线观看| 国产精品尤物福利片在线观看| 成人精品视频99在线观看免费| 日本成人黄色片| 一区二区亚洲精品国产| 色久欧美在线视频观看| 91免费视频网站| 国产精品美女久久久久久免费| 亚洲第一色中文字幕| 91日韩在线视频| 高跟丝袜一区二区三区| 国产91色在线|| 亚洲一区二区三区xxx视频| 国产精品一区二区三区免费视频| 亚洲电影免费观看| 97在线视频一区| 精品国产91久久久久久老师| 国产精品视频在线观看| 日韩欧美成人精品| 久久视频在线视频| 欧洲成人免费视频| 91国内揄拍国内精品对白| 成人写真福利网| 国产精品精品视频| 操人视频在线观看欧美| 日韩电影免费观看中文字幕| 欧美日韩中文字幕在线| 欧美不卡视频一区发布|