c++++11通過引入標準線程庫簡化了跨平臺多線程編程。1. 使用std::Thread創建線程,傳入可調用對象啟動執行;2. 通過join()等待線程結束或detach()分離線程獨立運行;3. 同步機制包括互斥鎖(std::mutex配合std::lock_guard)和條件變量(std::condition_variable)實現線程通信;4. 線程間數據傳遞可通過原子類型std::atomic、共享隊列等方法完成;5. 編譯時需注意不同平臺選項如gcc/clang需加-pthread,msvc默認支持較好。
c++11標準引入了對多線程的原生支持,這讓跨平臺的多線程編程變得比以前更簡單、更統一。相比依賴系統API(如windows的CreateThread或linux的pthread),用C++11的標準線程庫寫出來的代碼更容易移植,也更適合現代C++開發。
創建線程的基本方式
在C++11中,使用std::thread來創建一個新線程。構造時傳入一個可調用對象(函數、Lambda表達式、綁定表達式等)即可啟動線程。
#include <iostream> #include <thread> void threadFunc() { std::cout << "Hello from thread!" << std::endl; } int main() { std::thread t(threadFunc); t.join(); // 等待線程結束 return 0; }
- join() 表示主線程等待子線程完成后再繼續執行。
- 如果不希望等待,可以用 detach() 把線程分離出去獨立運行。
- 注意:一旦調用了 join() 或 detach(),就不能再對這個線程對象進行操作了。
跨平臺線程同步方法
多線程編程中,共享資源的訪問必須小心處理。C++11提供了幾種基本的同步機制:
立即學習“C++免費學習筆記(深入)”;
互斥鎖(mutex)
最常用的同步工具是std::mutex,配合std::lock_guard可以自動加鎖和釋放。
#include <mutex> std::mutex mtx; void safePrint(const std::string& msg) { std::lock_guard<std::mutex> lock(mtx); std::cout << msg << std::endl; }
- 使用RAII風格管理鎖資源,避免忘記解鎖。
- 若多個線程同時調用safePrint,會自動排隊執行。
條件變量(condition_variable)
當線程需要等待某個條件滿足時,可以用std::condition_variable配合mutex使用。
#include <condition_variable> std::condition_variable cv; std::mutex cvMtx; bool ready = false; void waitFunc() { std::unique_lock<std::mutex> lock(cvMtx); cv.wait(lock, []{ return ready; }); std::cout << "Condition met!" << std::endl; } void notifyFunc() { std::this_thread::sleep_for(std::chrono::seconds(1)); { std::lock_guard<std::mutex> lock(cvMtx); ready = true; } cv.notify_all(); }
- wait() 會阻塞直到被喚醒且條件為真。
- notify_all() 喚醒所有等待的線程。
線程通信與數據傳遞技巧
線程之間通信通常通過共享變量完成,但要注意數據競爭問題。除了用鎖之外,還可以考慮以下方法:
- 使用std::atomic類型安全地操作共享變量
- 用隊列結構作為消息通道(比如生產者-消費者模型)
- 避免頻繁加鎖,盡量設計成無鎖結構
例如:
#include <atomic> std::atomic<bool> flag(false); void worker() { while (!flag.load()) { // do work } std::cout << "Flag changed!" << std::endl; }
- load() 和 store() 是原子操作,不會引發競態。
- 不過仍需注意內存順序(memory_order),默認是memory_order_seq_cst。
編譯和運行注意事項
- 不同編譯器對C++11線程的支持略有差異:
- GCC 需要加上 -pthread
- Clang 同樣需要 -pthread
- MSVC一般默認支持較好
- Windows下使用MinGW時,確保鏈接了正確的線程庫
- 多線程程序調試建議使用日志輸出或斷點,避免打印干擾執行流程
基本上就這些。雖然看起來不復雜,但在實際開發中很容易忽略細節導致死鎖或競態條件,所以一定要仔細設計線程間的交互邏輯。