日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

CLR Via C# 3rd 阅读摘要 -- Chapter 28 – Primitive Thread Synchronization Constructs

發布時間:2024/10/8 C# 128 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CLR Via C# 3rd 阅读摘要 -- Chapter 28 – Primitive Thread Synchronization Constructs 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Class Libraries and Thread Safety

  • 線程同步是用來避免多個線程同時訪問共享數據時出現沖突;
  • 線程同步的障礙:
    • 1.極其乏味易錯;
    • 2.鎖嚴重影響性能;
    • 3.線程同步鎖在同一時間點僅允許一個線程訪問資源。
  • 設計程序時應該盡可能的避免線程同步,最好避免采用static字段的共享數據;
  • 嘗試使用值類型,因為它們總是拷貝傳遞的,因此每個線程在自身擁有的拷貝上操作。所以當多個線程同時以只讀方式訪問值類型共享數據時是安全的。
  • FCL保證所有的靜態方法是線程安全的;
  • 當一個線程構造一個對象,只有該線程擁有該對象的引用,其他線程不能訪問該對象;
  • 類型設計時應遵循的模式:確保所有的靜態方法多線程安全、所有的實例方法多線程不安全;
    一個例外:如果實例方法是用于協調多線程的,那么該實例方法也應該多線程安全。如CancellationTokenSource.Cancel方法。
  • Primitive User-Mode and Kernel-Mode Constructs

  • 兩種原生線程同步結構:
    • 用戶模式:速度很快,使用特定的CPU指令協調線程,協調工作由硬件完成。Windows系統不會檢測線程是否阻塞在用戶模式同步結構;
      線程池線程阻塞在用戶模式同步結構不會被當成阻塞,線程池不會創建新的線程來代替臨時阻塞的線程。
      采用該模式的線程會被系統搶占調度,可能導致線程被反復快速調度,從而會浪費CPU;
    • 核心模式:Windows操作系統提供,調用實現在系統內核的函數。當一個線程使用內核模式同步結構來請求其他線程持有的資源,Windows將阻塞該線程所以不會浪費CPU;
      線程在用戶模式與核心模式間互相轉換會嚴重損害性能;
    • 如果一個線程持有一個同步結構不再釋放它,等待該結構的線程將永遠被阻塞:
      • 活鎖:如果該同步結構是用戶模式,線程一直運行在CPU上;
      • 死鎖:如果該同步結構是核心模式,線程被阻塞住;
    • 活鎖與死鎖都很糟糕,但相比之下,活鎖更糟糕,因為活鎖既浪費CPU又浪費內存,而死鎖只浪費內存;
  • User-Mode Constructs

  • 原生的用戶模式結構:
    • 易變(volatile)結構:在一個簡單數據類型變量上執行原子讀或寫操作;
    • 聯鎖(Interlocked)結構:在一個簡單數據類型變量上執行原子讀和寫操作;
  • 易變結構確認讀或寫操作是否原子的非常重要,它們還控制這些原子操作的時機。聯鎖結構執行操作要比簡單的讀和寫操作復雜一些,它們也需要控制操作的時機;
  • 比如一個Int64的變量如果沒有正確對齊,那么當多線程讀寫該變量時,可能會出現只正確讀取前四字節或后四字節,這就是臟讀(torn read)?
  • System.Threading.Thread.VolatileWrite(), .VolatileRead(), .MemoryBarrier()靜態方法通常禁止C#編譯器、JIT編譯器、CPU進行優化;
  • 當線程通過共享數據進行通信時,對最后一個值的寫操作調用VolatileWrite(),對第一個值的讀操作調用VolatileRead();
  • C# volatile關鍵字:JIT編譯器會對標記為volatile的字段的讀寫進行VolatileWrite()和VolatileRead()處理;
  • 將來,C#不支持通過引用傳遞volatile字段到方法調用中;
  • 現在,Interlocked.Exchange(), .CompareExchange()只支持簡單值類型,將來還會提供對Object, IntPtr, Single, Double以及泛型版本的支持;
  • SimpleSpinLock的缺陷,當鎖出現競爭時,線程會不停輪轉,浪費CPU資源: internal struct SimpleSpinLock {private Int32 m_ResourceInUse; //0 = false (default), 1 = truepublic void Enter() {// Set the resource to in-use and if this thread// changed it from Free, then returnwhile (Interlocked.Exchange(ref m_ResourceInUse, 1) != 0) {// Black Magic goes here...}}public void Leave() {// Mark the resource as FreeThread.VolatileWrite(ref m_ResourceInUse, 0);} }
  • FCL提供的System.Threading.SpinWait
  • Thread.Sleep(),允許線程資源放棄時間片,休眠時間是近似值;
  • Thread.Yield(),告訴Windows在當前CPU上調度其他線程。如果當前CPU上有其他線程,返回true并結束調用線程的時間片,被調度線程結束自身的時間片之后,調用線程繼續。
  • Thead.SpinWait(),線程強制自己暫停,允許超線程CPU切換到其他線程。該方法會使用特別的CPU指令,如果CPU不支持超線程,該指令被忽略;
  • Win32 API:Sleep(), SwitchToThread(), YieldProcessor();
  • 當集合中的每一項都需要關聯鎖的時候,輕量級、內存友好的SpinLock是個好東西。但是要注意不要傳遞它的實例,因為是值類型,傳遞的是拷貝;
  • Kernel-Mode Constructs

  • 核心模式的同步結構比用戶模式的要慢許多,因為它們由Windows操作系統協調,此外每個核心對象上的方法調用都會導致調用線程從托管代碼轉換到本地用戶模式代碼再到本地核心模式代碼,然后再原路返回;
  • 核心模式同步結構提供哪些用戶模式所沒有的優點:
    • 當核心模式同步結構檢測到資源上出現競爭時,Windows阻塞競爭失敗的線程,因此不再浪費處理器資源;
    • 核心模式同步結構可以同步本地線程和托管線程;
    • 核心模式同步結構可以同步運行在同一臺機器上不同處理器上的線程;
    • 核心模式同步結構可以附上安全限制避免未經認證的帳號訪問他們;
    • 線程能夠被阻塞直到所有的核心模式同步結構都可用,或者任何一個可用;
    • 阻塞在核心模式同步結構上的線程可以設置一個timeout值;如果這段時間內沒能獲得期望的資源,那么不再阻塞以干點其他正事。
  • 原生的核心模式結構:
    • 事件(Events):事件是有內核管理的Boolean變量。當事件為false時,線程被阻塞。有兩種事件:AutoResetEventManualResetEvent
    • 信號量(Semaphore):信號量是內核管理的Int32變量。當信號量為0時,線程被阻塞;>0時,線程不被阻塞。
  • 核心模式結構的層次結構: WaitHandle|--EventWaitHandle|--|--AutoResetEvent|--|--ManualResetEvent|--Semaphore|--Mutex
  • 每個在核心模式同步結構上的方法調用都會出現完全內存保護;
  • SimpleWaitLock vs SimpleSpinLock
    當鎖上沒有競爭時,SimpleWaitLockSimpleSpinLock要慢許多,因為SimpleWaitLockEnterLeave方法會強制調用線程在托管代碼到核心代碼之間進行來回轉換;
    但是當鎖上有競爭時,SimpleWaitLock不會浪費CPU資源,而SimpleSpinLock會不停的輪轉CPU;
  • AutoResetEventManualResetEventSemaphore行為比較:
    • 當多個線程在AutoResetEvent上等待時,設置事件只會讓一個線程不再被阻塞;
    • 當多個線程在ManualResetEvent上等待時,設置事件會讓所有線程不再被阻塞;
    • 當多個線程在Semaphore上等待時,釋放信號量會讓releaseCount個線程不再被阻塞(relaseCountSemaphore.Release()方法的參數)。
  • 互斥體(Mutex)表現為一個同斥鎖;
  • Mutex很像AutoResetEvent或者Semaphore(count = 1),但有一些更復雜的邏輯:
    • 首先,Mutex對象通過查詢調用線程的ID記錄了哪個線程獲得了它。當線程調用ReleaseMutexMutex會確認是否為同一線程;
    • 其次,Mutex維護一個遞歸計數指出被獲得了多少次。只有當遞歸計數降為0時,其他線程才能獲取。
  • Mutex對象需要更多的內存,并且需要維護額外信息,所以會比較慢;
  • 如何當一個單獨的核心結構可用時調用方法?使用System.Threading.ThreadPool.RegisterWaitForSingleObject靜態方法。
  • 本章小結

    ??? 本章講述了原生的線程同步結構,首先介紹了類庫和線程安全性概念,然后對線程同步模式進行了分類:用戶模式與核心模式,接著詳細說明了這兩種同步模式的實現細節,并舉例進行了對比。

    轉載于:https://www.cnblogs.com/bengxia/archive/2010/07/01/1768923.html

    總結

    以上是生活随笔為你收集整理的CLR Via C# 3rd 阅读摘要 -- Chapter 28 – Primitive Thread Synchronization Constructs的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。