国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C#基本線程同步

2019-11-17 02:56:18
字體:
來源:轉載
供稿:網友
C#基本線程同步

0 概述

  所謂同步,就是給多個線程規定一個執行的順序(或稱為時序),要求某個線程先執行完一段代碼后,另一個線程才能開始執行。

  

第一種情況:多個線程訪問同一個變量

  1.一個線程寫,其它線程讀:這種情況不存在同步問題,因為只有一個線程在改變內存中的變量,內存中的變量在任意時刻都有一個確定的值;

  2.一個線程讀,其它線程寫:這種情況會存在同步問題,主要是多個線程在同時寫入一個變量的時候,可能會發生一些難以察覺的錯誤,導致某些線程實際上并沒有真正的寫入變量;

  3.幾個線程寫,其它線程讀:情況同2。

  多個線程同時向一個變量賦值,就會出現問題,這是為什么呢?

  我們編程采用的是高級語言,這種語言是不能被計算機直接執行的,一條高級語言代碼往往要編譯為若干條機器代碼,而一條機器代碼,CPU也不一定是在一個CPU周期內就能完成的。計算機代碼必須要按照一個“時序”,逐條執行。

  舉個例子,在內存中有一個整型變量number(4字節),那么計算++number(運算后賦值)就至少要分為如下幾個步驟:

  1. 尋址:由CPU的控制器找尋到number變量所在的地址;

  2. 讀取:將number變量所在的值從內存中讀取到CPU寄存器中;

  3. 運算:由CPU的算術邏輯運算器(ALU)對number值進行計算,將結果存儲在寄存器中;

  4. 保存:由CPU的控制器將寄存器中保存的結果重新存入number在內存中的地址。

  這是最簡單的時序,如果牽扯到CPU的高速緩存(CACHE),則情況就更為復雜了。

CPU結構簡圖圖1 CPU結構簡圖

  在多線程環境下,當幾個線程同時對number進行賦值操作時(假設number初始值為0),就有可能發生沖突:

  當某個線程對number進行++操作并執行到步驟2(讀取)時(0保存在CPU寄存器中),發生線程切換,該線程的所有寄存器狀態被保存到內存后后,由另一個線程對number進行賦值操作。當另一個線程對number賦值完畢(假設將number賦值為10),切換回第一個線程,進行現場恢復,則在寄存器中保存的number值依然為0,該線程從步驟3繼續執行指令,最終將1寫入到number所在內存地址,number值最終為1,另一個線程對number賦值為10的操作表現為無效操作。

  看一個例子:

[csharp]view plaincopy在CODE上查看代碼片usingSystem;
  • usingSystem.Threading;
  • namespaceEdu.Study.Multithreading.WriteValue{
  • classintn=0;
  • //將n加1
  • //執行完畢后n的值變為1,和返回值相同
  • intx=Interlocked.Add(refn,1);
  • //將n減1
  • x=Interlocked.Add(refn,-1);
  • Interlocked.Increment/Interlocked.Decrement方法演示
  • intn=0;
  • //對n進行自加操作
  • //執行完畢后n的值變為1,和返回值相同
  • intx=Interlocked.Increment(refn);
  • //對n進行自減操作
  • x=Interlocked.Decrement(refn);
  • Interlocked.Exchange方法演示
  • strings="Hello";
  • //用另一個字符串對象"OK"為s賦值
  • //操作完畢后s變量改變為引用到"OK"對象,返回"Hello"對象的引用
  • stringold=Interlocked.Exchange(refs,"OK");
  • Interloceked.CompareExchange方法演示
  • strings="Hello";
  • stringss=s;
  • //首先用變量ss和s比較,如果相同,則用另一個字符串對象"OK"為s賦值
  • //操作完畢后s變量改變為引用到"OK"對象,返回"Hello"對象的引用
  • stringold=Interlocked.CompareExchange(refs,ss,"OK");
  •   注意,原子操作中,要賦值的變量都是以引用方式傳遞參數的,這樣才能在原子操作方法內部直接改變變量的值,才能完全避免非安全的賦值操作。

    下面我們將前一節中出問題的代碼做一些修改,修改其ThreadWork方法,在多線程下能夠安全的操作同一個變量:

    [csharp]view%20plaincopy派生到我的代碼片application/x
    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 麻江县| 沧州市| 文登市| 丰都县| 娱乐| 安庆市| 海安县| 闽清县| 名山县| 天津市| 鹿泉市| 偏关县| 英吉沙县| 馆陶县| 大竹县| 普兰县| 德安县| 龙岩市| 景洪市| 山西省| 新干县| 蒙阴县| 郴州市| 黄龙县| 宣化县| 永和县| 昌吉市| 光泽县| 济宁市| 临猗县| 阿合奇县| 江北区| 天祝| 阿瓦提县| 比如县| 门源| 定州市| 土默特左旗| 信丰县| 长沙市| 尉氏县|