【轉】編寫高品質代碼改善C#程式的157個建議——建議89:在並行方法體中謹慎使用鎖

來源:互聯網
上載者:User

標籤:ref   無法   some   靜態類   cpu   length   針對   代碼   add   

 

建議89:在並行方法體中謹慎使用鎖

除了建議88所提到的場合,要謹慎使用並行的情況還包括:某些本身就需要同步啟動並執行場合,或者需要較長時間鎖定共用資源的場合。

在對整型資料進行同步操作時,可以使用靜態類Interlocked的Add方法,這就極大地避免了由於進行原子操作長時間鎖定某個共用資源所帶來的同步效能損耗。回顧建議83中的例子。

static void Main(string[] args)  {      int[] nums = new int[] { 1, 2, 3, 4 };      int total = 0;      Parallel.For<int>(0, nums.Length, () =>        {              return 1;          }, (i, loopState, subtotal) =>        {              subtotal += nums[i];              return subtotal;          },          (x) => Interlocked.Add(ref total, x)          );      Console.WriteLine("total={0}", total);      Console.ReadKey();  } 

理論上,針對total的加法操作,需要使用一個同步鎖,否則就無法避免一次torn read(即兩次mov操作所導致的欄位記憶體位址邊界對齊問題)。FCL通過提供Interlocked類型解決了這個問題。FCL用來解決簡單類型的原子性操作還提供了volatile關鍵字。不過這些都不是本建議所要討論的重點。FCL現有的原子性操作為我們同步整型資料的時候,帶來了效能上的提高。但是,在其他一些場合,我們卻不得不考慮因為同步鎖帶來的損耗。

來看一個例子:

static void Main(string[] args)  {      SampleClass sample = new SampleClass();      Parallel.For(0, 10000000, (i) =>    {          sample.SimpleAdd();      });      Console.WriteLine(sample.SomeCount);  }   class SampleClass  {      public long SomeCount { get; private set; }       public void SimpleAdd()      {          SomeCount++;      }  } 

這段代碼的輸出或許是:
8322580

顯然,這與我們的期待輸出10000000有很大的差距。為了保證輸出正確,必須為並行中的方法體加鎖(假設SampleClass是外部提供的API,無權進行源碼修改在其內部加鎖):

object syncObj = new object();  Parallel.For(0, 10000000, (i) =>{      lock (syncObj)      {          sample.SimpleAdd();      }  }); 

經過以上修改後,代碼輸出就正確了。但是,這段代碼也帶來了另外的問題。由於鎖的存在,系統的開銷也增加了,同步帶來的線程環境切換,使我們犧牲了CPU時間與空間效能。簡單地說,就是這段代碼還不如不用並行。在建議73中曾經提到過,鎖其實就是讓多線程變成單線程(因為同時只允許有一個線程訪問資源)。所以,我們需要謹慎地對待並行方法中的同步問題。如果方法體的全部內容都需要同步運行,就完全不應該使用並行。

 

 

轉自:《編寫高品質代碼改善C#程式的157個建議》陸敏技

【轉】編寫高品質代碼改善C#程式的157個建議——建議89:在並行方法體中謹慎使用鎖

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.