線程安全
競爭與原子操作
同步與鎖:
-
二元信號量(Semaphore)
-
互斥量(Mutex)
-
臨界區(Critical Section)
-
讀寫鎖(Read-Write Lock)
一個函數被重入的兩種情況:
- 多個線程同時執行這個函數;
- 函數自身調用自身;
可重入函數的特點:
-
不使用任何(局部)靜態或全局的非 const 變量;
-
不使用任何(局部)靜態或全局的非 const 變量的指針;
-
僅依賴於調用方提供的參數;
-
不依賴於任何單個資源的鎖;
-
不調用任何不可重入的函數。
volatile作用:
- 阻止編譯器爲了提高速度,將一個變量緩存到寄存器內而不寫回;
- 阻止編譯器調整操作 volatile 變量的指令順序(但是無法阻止 CPU 動態調度換序)。
C++ 中 new 包含的兩個步驟:
-
首先申請內存;
-
然後調用構造函數。
而 p = new T; 表示最後多了一步:將內存的地址賦給 p。
多線程內部情況
三種線程模型
Win/Linux 系統會在內核提供線程的支持,內核線程由多處理器或調度來實現併發。用戶實際使用的是存在於用戶態的用戶線程,用戶線程和內核線程不一定是數目對等的。
一對一模型
用戶線程和內核線程“一對一”,線程之間的併發是真正的併發。
優點:
- 多個線程的執行不會互相影響。
缺點: - 由於許多系統限制了內核線程的數量,所以用戶線程也受限;
- 許多操作系統內核線程調度,上下文切換的開銷較大,導致用戶線程的執行效率下降。
一般直接使用 API 或者系統調用創建的線程均爲一對一的線程。
多對一模型
多個用戶線程映射到一個內核線程上面,線程之間的切換由用戶態的代碼進行。
優點:
- 線程切換快速(上下文切換高效)
- 無限制的用戶線程數量
缺點:
- 線程之間會互相影響,一個用戶線程的阻塞會導致其他線程無法執行
多對多模型
- 線程切換快速(上下文切換高效)
- 無限制的用戶線程數量
- 一個用戶線程的阻塞會導致其他線程無法執行