C++11 標準庫引入 <thread>,提供 std::thread 類管理線程。核心功能:
std::thread t(callable, args...)。
t.join() 阻塞當前線程直到 t 結束。
t.detach() 讓線程獨立運行,主線程不再管理。
std::mutex、std::recursive_mutex、std::condition_variable、std::lock_guard、std::unique_lock。
std::atomic<T>、記憶體屏障。
std::async、std::future、std::promise、std::packaged_task。
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void task(int id) {
for (int i = 0; i < 5; ++i) {
cout << "Thread " << id << ": " << i << '\n';
this_thread::sleep_for(chrono::milliseconds(100));
}
}
int main() {
thread t1(task, 1); // 值傳遞參數
int x = 10;
thread t2([&x]{ x = 20; }); // Lambda 捕獲引用
thread t3(task, 2);
t1.join();
t2.join();
t3.join();
cout << "x = " << x << '\n'; // 20
return 0;
}
| 形式 | 說明 |
|---|---|
thread() | 空線程,無關聯執行緒 |
thread(const thread&) = delete | 不可複製 |
thread(Fn&&, Args&&...) | 啟動新線程執行 Fn(args...) |
thread(thread&&) noexcept | 移動建構,轉移所有權 |
注意:可 joinable() 的線程必須在析構前 join() 或 detach(),否則呼叫 std::terminate。
void byVal(int n) { n++; } // 複本
void byRef(int& n) { n++; } // 原物件
int v = 0;
thread t1(byVal, v); // v 不變
thread t2(byRef, std::ref(v)); // v 變為 1
t1.join(); t2.join();
預設以值傳遞(複製/移動),需用 std::ref/std::cref 明確傳引用。
thread t1(task);
thread t2 = std::move(t1); // t1 變為空,t2 擁有線程
// t1.join(); // 錯誤:t1 不再 joinable
t2.join();
mutex mtx;
int counter = 0;
void inc() {
lock_guard<mutex> lk(mtx);
++counter;
}
mutex mtx; condition_variable cv; bool ready = false;
void worker() {
unique_lock<mutex> lk(mtx);
cv.wait(lk, []{ return ready; });
// ...
}
void notify() {
{ lock_guard<mutex> lk(mtx); ready = true; }
cv.notify_one();
}
future<int> f = async(launch::async, []{ return 42; });
cout << f.get(); // 阻塞直到結果就緒
launch::async 強制新線程,launch::deferred 延遲到 get() 時同步執行。預設由實現決定。
std::async + future 簡化非同步任務。
mutex 保護,或用 atomic 無鎖編程。
async 或第三方庫(如 Boost.Thread, Intel TBB)。
detach() 除非極簡單的獨立任務,否則難以管理生命週期。
std::move 或 shared_ptr 避免拷貝。
C++11 為多線程提供了標準化、可移植的基礎設施。掌握 thread、mutex、condition_variable、future 核心組件,配合 RAII 鎖與移動語義,即可編寫安全高效的並發程式。進階主題如線程池、無鎖資料結構、平行算法(C++17)可在實踐中逐步深入。