基於鎖的併發資料結構練習題 (Practice - Lock-Based Data Structures)


Question 1 - 執行緒安全的定義 [recall]

面試官問:「你說這個資料結構是執行緒安全的,請給出精確定義。」


Question 2 - 序列化與設計目標 [recall]

什麼是序列化 (serialization)?併發資料結構設計的核心指導思想是什麼?


Question 3 - pop 介面設計 [recall]

threadsafe_stack 為何不像 std::stack<> 那樣提供分離的 top()pop()?


Question 4 - notify_one 的異常安全 [recall]

代碼 6.2 的佇列中,被 notify_one() 喚醒的執行緒在 wait_and_pop() 內建構 shared_ptr 時拋出異常,會發生什麼事?有哪三種解法?


Question 5 - dummy node 的作用 [recall]

細粒度鎖佇列為何要預先配置一個「虛擬節點 (dummy node)」?


Question 6 - 查詢表的底層結構選擇 [recall]

為細粒度鎖設計查詢表時,二元樹、有序陣列、雜湊表三者如何取捨?桶數為何預設 19?


Question 7 - 全表快照的死結預防 [application]

你要為 threadsafe_lookup_table 實作 get_map(),把所有桶的內容複製成一個 std::map。多個執行緒可能同時呼叫它,如何避免死結?


Question 8 - 有缺陷的 pop_head [application]

同事把細粒度佇列的 pop_head() 改成:先呼叫 get_tail() 存下 old_tail,再鎖 head_mutex,然後比較 head.get() == old_tail。請指出問題。


Question 9 - 單鎖佇列 vs 細粒度佇列 [analysis]

比較代碼 6.2/6.3(單一 mutex + std::queue)與代碼 6.6(head/tail 雙 mutex + 自建鏈結串列):併發度、複雜度、異常安全各有何差異?何時值得用細粒度版?


Question 10 - hand-over-hand locking 分析 [analysis]

threadsafe_list 每節點一把 mutex,迭代時交錯上鎖 (hand-over-hand locking)。分析:為何不會死結?併發度比單鎖串列好在哪?極限在哪?