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

首頁 > 編程 > C# > 正文

C# 線程同步詳解

2019-10-29 21:14:05
字體:
來源:轉載
供稿:網友

前言

當線程池的線程阻塞時,線程池會創建額外的線程,而創建、銷毀和調度線程所需要相當昂貴的內存資源,另外,很多的開發人員看見自己程序的線程沒有做任何有用的事情時習慣創建更多的線程,為了構建可伸縮、響應靈敏的程序,我們在前面介紹了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); }

C#,線程同步

編譯器如果檢查到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做更多的工作,因此,這種自旋鎖應該用于保護那些執行的非常快的代碼。

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


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩专区在线| 亚洲福利视频专区| 成人信息集中地欧美| 亚洲大胆人体在线| 中文字幕精品—区二区| 久久久久久久999精品视频| 97在线观看视频国产| 伊人精品在线观看| 一区二区亚洲欧洲国产日韩| 最近2019中文免费高清视频观看www99| 欧美国产日韩一区二区| 久热精品视频在线观看| 精品国产乱码久久久久久天美| 欧美电影在线观看完整版| 久久视频精品在线| 91国产美女在线观看| 国产主播欧美精品| 91精品视频免费| 国产在线播放不卡| www.久久撸.com| www.日韩不卡电影av| 亚洲精品自拍偷拍| 人人爽久久涩噜噜噜网站| 最近2019好看的中文字幕免费| 亚洲影院污污.| 日韩电影免费在线观看中文字幕| 精品国产31久久久久久| 国产精品www网站| 91色在线观看| 亚洲欧洲在线视频| 国产成人亚洲综合91精品| 国产午夜精品理论片a级探花| 美日韩丰满少妇在线观看| 国产精自产拍久久久久久| 精品av在线播放| 69久久夜色精品国产69| 亚洲精品之草原avav久久| 国产精品视频导航| 亚洲丝袜在线视频| 国产精品一区二区久久久| 欧美成在线观看| 不卡av电影在线观看| 日韩av在线免费观看一区| 亚洲综合精品一区二区| 97热精品视频官网| 亚洲少妇中文在线| 97在线精品国自产拍中文| 国产日韩中文在线| 在线看欧美日韩| 久久伊人精品视频| 日韩美女福利视频| 国产91色在线播放| 亚洲a区在线视频| 性色av一区二区三区在线观看| 国产成人精品久久亚洲高清不卡| 久久色免费在线视频| 日韩成人小视频| 国产手机视频精品| 成人妇女免费播放久久久| 日韩三级成人av网| 在线看福利67194| 亚洲a在线观看| 亚洲第一精品久久忘忧草社区| 久久视频这里只有精品| 国产精品久久久久久久久久小说| 欧美精品少妇videofree| 亚洲free性xxxx护士hd| 国模gogo一区二区大胆私拍| 中文字幕亚洲激情| 最近2019中文字幕第三页视频| 丝袜美腿亚洲一区二区| 久久久久久久久国产| 亚洲精品一区中文字幕乱码| 精品视频在线播放免| 国产视频精品在线| 中文字幕成人在线| 日韩免费在线看| 精品伊人久久97| 欧美视频一区二区三区…| 亚洲欧美成人网| 亚洲欧洲一区二区三区久久| 欧美老少做受xxxx高潮| 亚洲一区精品电影| 欧美激情一区二区三区高清视频| 国产美女高潮久久白浆| 国产精品揄拍500视频| 国产91在线播放九色快色| 午夜精品一区二区三区视频免费看| 欧美激情va永久在线播放| 成人激情黄色网| 亚洲国产精品免费| 久久亚洲精品国产亚洲老地址| 国产成人一区二区| 国色天香2019中文字幕在线观看| 国产精品爱久久久久久久| 欧美日韩国产中文精品字幕自在自线| 亚洲三级 欧美三级| 亚洲精品美女久久| 国产精品第三页| 91牛牛免费视频| 久久久久五月天| 精品视频在线播放| 最近2019好看的中文字幕免费| 日韩va亚洲va欧洲va国产| 欧美日韩国产中字| 日韩免费av在线| 疯狂欧美牲乱大交777| 色婷婷久久一区二区| 欧美激情第1页| 久热精品视频在线观看一区| 北条麻妃一区二区在线观看| 另类视频在线观看| 亚洲电影免费观看高清完整版在线观看| 亚洲精品国产精品国产自| 国产亚洲aⅴaaaaaa毛片| 91久久久久久久一区二区| 亚洲精品美女久久久久| 日韩专区中文字幕| 亚洲一区二区三区成人在线视频精品| 欧美一级视频在线观看| 国产亚洲欧美日韩精品| 亚洲视频综合网| 国产成人av在线| 久久精品99无色码中文字幕| 在线精品播放av| 激情久久av一区av二区av三区| 欧美成年人视频网站欧美| 成人中文字幕+乱码+中文字幕| 久久影视电视剧凤归四时歌| 亚洲精品电影在线观看| 国产成人鲁鲁免费视频a| 日韩男女性生活视频| 欧美精品videos| 国产精品国模在线| 91在线|亚洲| 视频在线一区二区| 国产第一区电影| 国产精品69久久久久| 久久青草精品视频免费观看| 久久九九全国免费精品观看| 日韩中文字幕精品视频| 国产玖玖精品视频| 欧美—级高清免费播放| 欧美激情影音先锋| 亚洲欧美国产一区二区三区| 欧洲美女7788成人免费视频| 亚洲欧美在线免费| 久久夜色精品国产欧美乱| 久久影院中文字幕| 国产精品久久久久免费a∨大胸| 亚洲欧美日韩精品久久亚洲区| 国产日韩精品在线观看| 亚洲网站视频福利| 91精品久久久久久久| 日韩av免费在线播放| 成人午夜激情网| 精品伊人久久97| 91精品啪aⅴ在线观看国产| 欧美日韩美女视频| 久久精品国产精品| 性欧美亚洲xxxx乳在线观看| 97免费在线视频| 88国产精品欧美一区二区三区| 久久精品国亚洲|