天天看點

.NET中的線程與異步(筆記)

翻出了之前記錄的筆記,基本涵蓋了.NET中線程和異步的相關概念。可以提供一個學習的方向。

工作者線程

IO線程

全局隊列(QueueUserWorkItem、Timer總是放入全局)

本地隊列

如果本地隊列有任務,則排程本地隊列

如果本地隊列沒有任務則去其它工作者線程中排程

如果所有工作者線程本地隊列都沒有任務則去全局隊列取任務排程

如果全局隊列也沒有任務則睡眠等待

如果睡眠了太長時間則自己醒來銷毀自己

從全局隊列取到本地隊列采用 FIFO 算法 從本地隊列取出時,采用 LIFO 算法 子任務、嵌套任務會被配置設定線上程的局部隊列中

AsyncLocal

ThreadLocal

ExecutionContext

SynchronizationContext(抽象的内容,基于ExecutionContext)

https://blogs.msdn.microsoft.com/pfxteam/2012/06/15/executioncontext-vs-synchronizationcontext/

http://stackoverflow.com/questions/9562836/whats-the-meaning-of-usetaskfriendlysynchronizationcontext

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

所有的Timer隻有一個線程,排程具體任務時使用線程池

避免重複執行,使用Change方法

因為不同的核心通路一個核心的cache發生的問題 [StructLayout(LayoutKind.Explicit)] [FieldOffset(64)]

BeginXXX、EndXXX

HTTP(RFC 2616) 用戶端應用程式到一個伺服器的并發連接配接數不應超過2個。 FCL強制了這個規則,除非重新指定"ServicePointManager.DefaultConnectionLimit"

指定 FileOptions.Asynchronous 盡量使用 BeginRead,否則盡量使用Read

<code>章節:27.8.8</code>

.NET中的線程與異步(筆記)

FCL法則

靜态方法保證線程安全

執行個體方法不保證

在硬體中發生

線程将一直在cpu上運作,稱作“活鎖”

在作業系統中發生

windows會堵塞線程使它不再浪費cpu時間

線程将一直堵塞,稱作“死鎖”

windows作業系統檢測不到一個線程在一個基元使用者模式中構造上堵塞了。是以線程池不會建立一個新的線程來替換這種臨時堵塞。
活鎖浪費cpu時間和記憶體,死鎖隻浪費記憶體 同時使用稱作:混合模式構造

它包含一個簡單的資料類型的變量上執行原子性的讀或寫操作

它包含一個簡單的資料類型的變量上執行原子性的讀和寫操作

相關FCL類型 1.Interlocked 2.SpinWait 3.SpinLock
WaitHandle EventWaitHandle AutoResetEvent ManualResetEvent Semaphore Mutex
ManualResetEventSlim SemaphoreSlim CountdownEvent(與SemaphoreSlim相反) Monitor Barrier(多線程協調)

任務使用的記憶體比線程少的多,建立和銷毀所需的時間也少的多(複用線程)

線程池根據可用CPU數量自動伸縮任務規模

每個任務完成一個階段後,運作的任務線程回到線程池,以便在那裡接受新任務

線程池是站在整個程序的高度觀察任務,是以,它能更好的排程這些任務,減少程序中的線程數,并減少上下文切換