並行 API練習題 (Practice - Concurrency API)

Question 1 - 回傳值與例外 [recall]

同事用 std::thread t(doAsyncWork); 執行會回傳 int 的函式,問你要怎麼拿到回傳值;另外若 doAsyncWork 丟出例外會發生什麼事?

Question 2 - Thread 三種意義與耗盡 [recall]

面試官問:「C++ 並行程式中 thread 有哪三種意義?另外 doAsyncWork 已宣告 noexceptstd::thread t(doAsyncWork); 還可能丟例外嗎?」

Question 3 - 預設 launch policy [recall]

程式碼審查時你看到 auto fut = std::async(f);,作者堅稱「f 一定會在另一條執行緒上跑」——這個說法正確嗎?

Question 4 - 高負載才出現的無窮迴圈 [application]

產品在測試環境一切正常,但正式環境高負載時 while (fut.wait_for(100ms) != std::future_status::ready) { ... } 偶爾永遠跑不完(fut 來自 std::async(f))——請診斷原因並給出修正。

Question 5 - 預設政策的安全檢查表 [recall]

學弟問:「什麼情況下用 std::async 的預設 launch policy 才安全?哪些情況必須改指定 std::launch::async?」

Question 6 - Joinable 解構的後果 [recall]

某函式在 return false; 的路徑上讓一個仍 joinable 的 std::thread 離開 scope——會發生什麼事?又有哪些 std::thread 是 unjoinable?

Question 7 - ThreadRAII 設計要點 [application]

你要實作一個 ThreadRAII 類別在解構子中自動 join/detach。請說明:為何解構子要先呼叫 t.joinable()?為何 std::thread 成員要宣告在最後?宣告了解構子之後 move 操作怎麼辦?

Question 8 - 為何選擇終止程式 [analysis]

標準委員會為何讓 joinable std::thread 的解構直接終止程式,而不是隱式 join 或隱式 detach?以 doWork 中 lambda 以 reference 捕獲區域變數 goodVals 的情境,分析兩個替代方案各自的問題。

Question 9 - Future 解構子的正常與例外 [recall]

面試官問:「future 的解構子通常做什麼?什麼情況下它會阻塞?」

Question 10 - packaged_task 的 future [recall]

同事擔心 auto fut = pt.get_future();(pt 是 std::packaged_task<int()>)的 fut 會在解構時阻塞,並問把 pt 交給 std::thread 時為何要 std::move

Question 11 - 事件通訊四方案比較 [recall]

偵測任務要通知反應任務「事件已發生」,candidate 方案有:純 condvar、輪詢 atomic flag、condvar+flag、std::promise<void> + future——各有什麼問題?void future 的兩個代價是什麼?

Question 12 - 暫停執行緒與懸掛 [analysis]

detect()ThreadRAII(DtorAction::join)包住一條執行緒,lambda 內先 p.get_future().wait() 暫停自己;若在 p.set_value() 之前的程式碼拋出例外,會發生什麼事?請完整推理因果鏈,並說明多個反應任務的版本要怎麼寫。

Question 13 - atomic vs volatile 分工 [recall]

面試快問:std::atomicvolatile 各自的用途是什麼?兩條執行緒各對 volatile int vc(0); 執行一次 ++vc,結果一定是 2 嗎?

Question 14 - atomic 複製與 auto 推導 [application]

下列程式碼哪幾行無法編譯?該怎麼改?另外若 xvolatile intauto y = x; 中 y 的型別是什麼?
std::atomic<int> x; auto y = x; y = x;