問題彙總解答
| 問題 | 解答 |
| 線程是否可復用? | 不可。std::thread 對象一旦 join()/detach() 即與可執行體綁定結束,無法重新啟動。需創建新線程。 |
| 構造時才能指定方法? | 否。可默認構造 std::thread t; 後通過 t = std::thread(func); 移動賦值指定。 |
| 運行結束後狀態? | 線程函數返回 → 線程終止。std::thread 對象若未 join/detach 析構時會調用 std::terminate。已 join 狀態為「無關聯」。 |
| Windows 構造/析構開銷? | 中等。涉及內核對象創建(約幾微秒)。高頻短任務建議**線程池**。 |
| 等待鎖的線程在哪?佔用 CPU? | 在**內核等待隊列**中**休眠**,**不佔用 CPU**。調度器喚醒時才消耗時間片。 |
線程池簡易示例
class ThreadPool {
std::vector workers;
std::queue> tasks;
std::mutex mtx; std::condition_variable cv; bool stop = false;
public:
ThreadPool(size_t n) { for (size_t i=0;i task; { std::unique_lock lk(mtx); cv.wait(lk, [this]{return stop||!tasks.empty();}); if(stop&&tasks.empty()) return; task=std::move(tasks.front()); tasks.pop(); } task(); } }); }
template void enqueue(F&& f) { { std::unique_lock lk(mtx); tasks.emplace(std::forward(f)); } cv.notify_one(); }
~ThreadPool() { { std::unique_lock lk(mtx); stop=true; } cv.notify_all(); for(auto& t:workers) t.join(); }
};
建議
- CPU 密集型任務:線程數 = 邏輯核心數。
- IO 密集型:線程數 = 核心數 × (1 + 平均等待/計算比)。
- 優先使用
std::async、std::packaged_task 或成熟庫(Boost.Thread、Intel TBB、folly)。