# 執行緒(Thread) **定義:執行緒是CPU利用的基本單位** 包含: * 執行緒識別號(Thread ID) * 程式計數器(Program Counter) * 註冊集(Register Set) * 堆疊(Stack 與同一進程的其他執行緒共享: * 程式碼段(Code Section) * 資料段(Data Section) * 其他資源 # 單執行緒和多執行緒的進程 * 傳統的單執行緒進程具有單一的控制執行緒。 * 多執行緒進程可以同時執行多個任務。 範例: 1. 忙碌的網頁伺服器有許多同時存取的客戶端。 2. 如果網頁伺服器運行為傳統的單執行緒過程,它一次只能為一個客戶端提供服務...速度慢! # 多執行緒伺服器架構的優點 1. 回應速度:如果進程的某部分被阻塞,可能允許持續執行,尤其對於使用者界面非常重要。 2. 資源共享:執行緒共享進程的資源,比共享記憶體或訊息傳遞更容易。 3. 經濟性:比起建立進程,執行緒創建成本較低,執行緒切換的開銷低於內文切換。 4. 擴展性:進程能夠利用多核架構的優勢。 # 多核編程 * 近年趨勢:將多個計算核心放置在單一晶片上。每個核心對作業系統看來都像是獨立的處理器。 * 多核編程提供了更有效地使用多核心和改進並行性的方法。 * 平行性(Parallelism)表示系統可以同時執行多個任務。 * 並行性(Concurrency)支持多個任務同時進展。 多核或多處理器系統給程序員帶來挑戰,其中包括: * 活動分配 * 平衡:某些任務可能對整個過程的價值貢獻不如其他任務。 * 數據分割 * 數據依賴:當一個任務依賴於另一個任務的數據時,必須確保任務的執行是同步的。 * 測試和調試 ## 多核編程--平行處理的類型 * 數據平行處理 - 在多個核心之間分發相同數據的子集,對每個子集進行相同的操作。 * 任務平行處理 - 將執行緒分佈在多個核心之間,每個執行緒執行獨特的操作。 # 阿姆達爾定律(Amdahl’s Law) ***阿姆達爾定律指出當將額外的核心添加到同時具有串行和并行組件的應用程序時,可以獲得的性能增益。*** 公式:speedup<=1/(S+(1-S)/N) * S代表串行部分 * N代表處理核心數量 Ex:如果應用程序是75%并行/ 25%串行,在從1個核心到2個核心的過程中,速度提升了1.6倍。 **當N接近無限時,速度提升趨近於1 / S。** # 用戶執行緒和內核執行緒 用戶執行緒-由用戶級執行緒庫進行管理 三個主要的執行緒庫: 1. POSIX Pthreads 2. Windows執行緒 3. Java執行緒 內核執行緒 - 受內核支持 EX: 1. Windows 2. Linux 3. Mac OS X 4. iOS 5. Android # 多對一 **就是多個用戶級執行緒映射到單個內核執行緒。** * 執行緒管理由用戶空間中的執行緒庫進行。 * 效率高 * 但如果一個執行緒進行了阻塞系統調用,整個進程將被阻塞 * 在多核系統上,多個執行緒可能無法並行運行,因為同一時間只能有一個執行緒在內核中運行 * 目前很少有系統使用這種模型,因為無法充分利用多核系統。 # 一對一 **即每個用戶級執行緒映射到一個內核執行緒。** * 比多對一提供更多的並發性,因為當一個執行緒進行阻塞系統調用時,允許另一個執行緒運行 * 比多對一具有更多的並發性:允許多個執行緒在多處理器上並行運行 * EX: * Windows * Linux # 多對多 **允許多個用戶級執行緒映射到多個內核執行緒(多路復用)。** * 一般情況下並不常見 # 執行緒庫(Thread Libraries) 執行緒庫為程式設計師提供了建立和管理執行緒的應用程式介面(API)。 實作方式主要有兩種: 1. 完全在使用者空間中實作的庫,不需要內核支援。 2. 受操作系統支援的內核級庫。 以下列舉三種主要的執行緒庫: 1. POSIX Pthreads * POSIX 標準的擴展,可以提供作為使用者或內核級別的庫。 2. Windows Threads * 可在 Windows 系統上使用的內核級庫。 3. Java Threads * Java 執行緒 API 允許直接在 Java 程式中建立和管理執行緒。 # 大中央調度(GCD) ***適用於 macOS 和 iOS 作業系統*** * 擴展了 C、C++ 和 Objective-C 語言、API 和運行時庫,並且類似於 OpenMP,GCD 管理了大部分的執行緒細節 * GCD 通過將區塊放入調度隊列來安排運行時執行。當從隊列中移除時,分配給可用的執行緒池中的執行緒。 分成兩種類型的調度隊列: 1. 串行(serial) - 區塊按照先進先出(FIFO)順序移除,每個進程都有一個隊列,稱為主隊列(main queue)。程式設計師可以在程式中創建其他串行隊列。 2. 並行(concurrent) - 區塊按照先進先出(FIFO)順序移除,但可能同時移除多個,因此允許多個區塊並行執行。 # 執行緒問題 1. 在多執行緒程式中,fork()和exec()系統調用的語義會改變。 2. 信號處理問題 3. 取消目標執行緒 4. 執行緒本地存儲 5. 調度器激活 # 信號處理 * 信號在UNIX系統中用於通知進程發生特定事件。 * 信號處理程序用於處理信號 1. 特定事件產生信號。 2. 信號傳遞給一個進程。 3. 信號由兩種信號處理程序之一處理: * 預設處理程序 * 用戶定義處理程序 * 每個信號都有預設的處理程序,在處理信號時內核運行。 * 用戶定義的信號處理程序可以覆蓋默認處理程序。 * 對於單執行緒,信號傳遞給進程。 * 在多執行緒環境中,信號的傳遞方式如下: 1. 將信號傳遞給引發信號的特定執行緒。 2. 將信號傳遞給進程中的每個執行緒。 3. 將信號傳遞給進程中的特定某些執行緒。 4. 指定特定的執行緒來接收進程中所有信號。 # 執行緒取消 有兩種一般的取消方法: 1. 異步取消立即終止目標執行緒。 2. 延遲取消允許目標執行緒定期檢查是否應該被取消。 **如果執行緒已經禁用了取消,則取消請求會保持為待處理,直到執行緒啟用它為止。默認類型是延遲型,即只有在執行緒到達取消點時才會發生取消。** # 調度程序激活(Scheduler Activations) **是一種調度機制,用於管理多對多和雙級執行緒模型中的內核執行緒數量,需要通信以維護應用程序分配的適當數量的內核執行緒。** * 通常使用介於用戶線程和內核線程之間的中間數據結構 - 輕量進程(LWP) # Windows執行緒 * 是Windows應用程序的主要API。 * 實現了一對一。 * 位於內核層級。 * 每個執行緒包含以下內容: * 執行緒ID * 代表處理器狀態的註冊集 * 在執行緒在用戶模式或內核模式運行時使用的單獨的用戶和內核堆棧 * 由運行時庫和動態連接庫(DLL)使用的私有數據存儲區域。 主要的執行緒(Thread)資料結構包括: * ETHREAD(執行緒管理塊):包含指向執行緒所屬的進程(Process)和 KTHREAD(內核執行緒塊)的指針,位於內核空間。 * KTHREAD(內核執行緒塊):包含調度和同步信息、內核模式堆棧、指向 TEB(執行緒環境塊)的指針,位於內核空間。 * TEB(執行緒環境塊):執行緒ID、用戶模式堆棧、執行緒本地存儲(Thread-Local Storage,TLS),位於用戶空間。 # Linux執行緒 * Linux並不區分進程和執行緒。 * Linux將它們稱為任務(tasks)而非執行緒。 * 執行緒創建是通過clone()系統調用完成的。 * clone()允許子任務與父任務(進程)共享地址空間。 * 通過標誌來控制行為。 * struct task_struct 指向進程數據結構(共享或獨特)。 # 本章重點 ***1. 每個執行緒可以執行相同程式的不同行號(指向不同位置)的程式碼。 2. Parallel: 同時發生的。 3. Concurrent: 在不同的時間進行工作。 4. 多對多模型允許根據系統資源創建足夠的核心執行緒。 5. Class -> type -> make an instant -> real object can run***