翻出了之前記錄的筆記,基本涵蓋了.NET中線程和異步的相關概念。可以提供一個學習的方向。
線程類型
工作者線程
IO線程
線程池
全局隊列(QueueUserWorkItem、Timer總是放入全局)
本地隊列
工作者線程調度流程
如果本地隊列有任務,則調度本地隊列
如果本地隊列沒有任務則去其它工作者線程中調度
如果所有工作者線程本地隊列都沒有任務則去全局隊列取任務調度
如果全局隊列也沒有任務則睡眠等待
如果睡眠了太長時間則自己醒來銷毀自己
從全局隊列取到本地隊列采用 FIFO 算法
從本地隊列取出時,采用 LIFO 算法
子任務、嵌套任務會被分配在線程的局部隊列中
線程的開銷
上下文切換
數據
AsyncLocal
ThreadLocal
ExecutionContext
SynchronizationContext(抽象的內容,基於ExecutionContext)
參考資料
https://blogs.msdn.microsoft.com/pfxteam/2012/06/15/executioncontext-vs-synchronizationcontext/
https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
Timer
所有的Timer只有一個線程,調度具體任務時使用線程池
避免重復執行,使用Change方法
偽共享
因為不同的內核訪問一個內核的cache發生的問題 [StructLayout(LayoutKind.Explicit)] [FieldOffset(64)]
異步模型
APM(異步編程模型)
BeginXXX、EndXXX
HTTP(RFC 2616) 客戶端應用程序到一個服務器的並發連接數不應超過2個。
FCL強制了這個規則,除非重新指定"ServicePointManager.DefaultConnectionLimit"
FileStream
指定 FileOptions.Asynchronous 盡量使用 BeginRead,否則盡量使用Read章節:27.8.8
異步編程模型
線程同步
類庫和線程安全
FCL法則
靜態方法保證線程安全
實例方法不保證
基元用戶模式和內核模式
用戶模式
在硬件中發生
線程將一直在cpu上運行,稱作“活鎖”
內核模式
在操作系統中發生
windows會堵塞線程使它不再浪費cpu時間
線程將一直堵塞,稱作“死鎖”
windows操作系統檢測不到一個線程在一個基元用戶模式中構造上堵塞了。所以線程池不會創建一個新的線程來替換這種臨時堵塞。
活鎖浪費cpu時間和內存,死鎖只浪費內存 同時使用稱作:混合模式構造
用戶模式構造
易失構造
它包含一個簡單的數據類型的變量上執行原子性的讀或寫操作
互鎖構造
它包含一個簡單的數據類型的變量上執行原子性的讀和寫操作
相關FCL類型
1.Interlocked
2.SpinWait
3.SpinLock
內核模式構造
相關FCL類型
WaitHandle
EventWaitHandle
AutoResetEvent
ManualResetEvent
Semaphore
Mutex
混合模式構造
相關FCL類型
ManualResetEventSlim
SemaphoreSlim
CountdownEvent(與SemaphoreSlim相反) Monitor
Barrier(多線程協調)
lock Monitor
Task優勢
- 任務使用的內存比線程少的多,創建和銷毀所需的時間也少的多(復用線程)
- 線程池根據可用CPU數量自動伸縮任務規模
- 每個任務完成一個階段后,運行的任務線程回到線程池,以便在那里接受新任務
- 線程池是站在整個進程的高度觀察任務,所以,它能更好的調度這些任務,減少進程中的線程數,並減少上下文切換

