進階執行緒管理練習題 (Practice - Advanced Thread Management)


Question 1 - 簡單執行緒池的 worker 迴圈 [recall]

代碼 9.1 的 worker_thread() 主迴圈做了哪些事?取不到任務時為什麼要呼叫 std::this_thread::yield()?


Question 2 - 為什麼需要 function_wrapper [recall]

可等待任務的執行緒池(代碼 9.2)為何不能繼續用 std::function<void()> 作任務佇列的元素型別?


Question 3 - submit() 如何回傳 future [recall]

描述代碼 9.2 中 submit() 從收到可呼叫物件到回傳 std::future<> 的完整流程。


Question 4 - thread_local 本地任務佇列 [recall]

代碼 9.6 中本地佇列宣告為 static thread_local std::unique_ptr<std::queue<function_wrapper>>,為何本地佇列可用普通 std::queue?為何要用 unique_ptr?


Question 5 - 工作竊取佇列的前端與後端 [recall]

代碼 9.7 的 work_stealing_queue 中,擁有者的 push()/try_pop() 與竊取者的 try_steal() 分別操作 deque 的哪一端?為什麼這樣設計?


Question 6 - interruption_point() 的行為 [recall]

interruption_point() 做什麼事?為什麼光靠它不足以中斷所有執行緒?


Question 7 - 池上快速排序死結 [application]

你把平行快速排序改到固定大小的執行緒池上:每層遞迴 submit() 一半資料再等待 future,結果所有 worker 卡死。診斷原因並給出修法。


Question 8 - 應用退出時關閉後台執行緒 [application]

桌面應用有多條 interruptible_thread 後台執行緒監視檔案系統。使用者按下退出,你會怎麼有序地關閉它們?為何不「中斷一條就 join 一條」?


Question 9 - 中斷條件變數等待的競爭 [analysis]

天真版 interruptible_wait(cv, lk)(代碼 9.10)有哪兩個缺陷?比較 wait_for(1ms) 輪詢(代碼 9.11)與 condition_variable_any + custom_lock(代碼 9.12)兩種解法的取捨。


Question 10 - 任務佇列設計的演進 [analysis]

比較執行緒池三代任務佇列設計:單一全域佇列、thread_local 本地佇列、本地佇列 + 工作竊取。各解決什麼問題?又引入什麼新問題?