2013-02-26 77 views
11

當一個互斥鎖已經被T1鎖定,並且T2試圖鎖定它時,T2的過程是什麼?互斥鎖的實現和信號發送

我覺得是這樣的:

-T2試圖鎖定,失敗,也許自旋鎖了一下,然後調用產量...
-T2安排執行幾次,試圖鎖定失敗,收益率...
-Eventually T1解鎖,T2安排執行和管理來鎖定互斥...

不T1開鎖信號明確地向調度或其他線程互斥量是解鎖?或者它只是解鎖,並讓調度程序安排阻塞的線程,當它覺得適合這樣做(又稱調度程序沒有封鎖線程的概念,並不把它們視爲特殊)?

+1

'我認爲'互斥原則保證沒有2個或更多線程同時進入臨界區。現在,無論您是否嘗試鎖定互斥鎖,或者您只是忙於等待互斥鎖被釋放,都取決於您如何實現互斥鎖以及互斥鎖的需求。例如,VxWorks等RTOS中的'mutex'實現優先級上限協議,在通用OS(GPOS)中可能不需要這種協議。 – Raj 2013-02-26 13:34:31

回答

3

簡而言之:是的,也許......

這是實現細節,並且它很難說沒有你所談論的最起碼知道哪個操作系統。通常,解鎖互斥鎖只會將等待的線程標記爲「可運行」,但不會(必然)在當時調用調度程序 - 即使調用調度程序,也不表示T2將成爲下一個線程跑步。

在Linux中,代碼輸入mutex_unlock(),它檢查是否有任何等待任務(通過檢查鎖定計數是否小於零 - 它從1開始解鎖,單個鎖定請求將其歸零,進一步嘗試鎖定會使其消極)。如果還有一個等待進程,它會調用一個「慢速路徑解鎖」,它通過一些重定向功能來允許實現細節,最終在__mutex_unlock_common_slowpath之後 - 稍後幾行,有一個呼叫到wake_up_process,最終結束在try_to_wake_up中 - 它基本上只是將任務排隊爲「準備運行」,然後調用調度程序(通過幾層功能!)

+0

所以你說在Linux的線程上,這些塊被標記爲不可運行(因此在它被標記爲可運行之前不會計劃它) – NoSenseEtAl 2013-02-26 13:59:35

+0

是的,這是正確的。假設你正在使用內核互斥鎖,這可能不是什麼,例如,pthread_mutex實現。 – 2013-02-26 14:00:29

+0

很好的答案......順便說一句,沒有我煩擾你很多...你能否快速地說,如果futex在某種意義上與此不同。 – NoSenseEtAl 2013-02-26 14:03:13

6

這取決於您的操作系統。我已經看到了旋轉,旋轉了yield,內核中的通用條件變量,用戶級控制的調度和具有內核支持的專用鎖定原語。

紡紗和旋轉yield有可怕的表現。理論上用戶級控制的調度(見Scheduler activations)應該具有最好的性能,但據我所知,沒有人在任何情況下都能正常工作。內核中的通用條件變量和具有內核支持的專用鎖定原語應該與Linux中的futex或多或少地相同,作爲後者的最佳示例。

有些情況下,紡紗可以有更好的表現。在Solaris中,內核中的某些鎖定基元具有自適應模式,只要持有鎖的進程在不同的CPU上運行,鎖就會自動旋轉。如果鎖主人睡覺或被搶先,鎖侍者也會入睡。在其他內核中有一些類鎖,其中鎖擁有者不能在搶鎖時被搶佔或睡眠,所以在這些情況下,旋轉也很有效。一般來說,特別是在用戶區,紡紗有這樣可怕的墮落情況(紡紗過程一直在旋轉,直到它被搶佔,讓鎖主人跑),這對性能來說是非常糟糕的。請注意,像futex這樣的專用鎖定基元可以實現像這樣的優化,這是通用條件變量通常無法實現的。

+0

不錯的答案,但是「紡紗和紡紗的產量有可怕的表現」應該是合格的......我可以想象在競爭很少的情況下,在螺旋鎖速度很快的情況下,工作量較低。 – NoSenseEtAl 2013-02-26 13:49:38

+1

沒有爭用時,所有的鎖都非常有效。當競爭很激烈時,精心設計的鎖定方法也是有效的。它還取決於可用處理器的數量 - 單個處理器系統上的「旋轉」等待很糟糕,因爲當前持有該鎖的其他線程無法運行,並且T2正在使用所有CPU來檢查T1誰沒有運行已經釋放鎖 - 這是非常無用的CPU時間使用。 – 2013-02-26 13:56:12

+0

@Mats我正在考慮多核系統,但是我同意你的單核心。 – NoSenseEtAl 2013-02-26 14:04:08

1

說,我們有以下情形:

1. T1 got M1. M1 locked. 
2. T2 tries to get M1 and gets blocked as M1 is locked. 
3. T3 tries to get M1 and gets blocked as M1 is locked. 
4. ...some time later... 
5. T1 unlocks M1.* 
6. T2 got M1. 
7. T3 is unblocked and tries to get M1 but is blocked again as T2 got M1 first. 

*系統調用,解鎖,應該通知所有阻止被封鎖互斥的鎖通話任務/進程/線程 。他們然後安排執行。這並不意味着他們被執行,因爲可能已經有人在執行。正如其他人所說,這取決於實施過程是如何完成的。如果你真的想學好這個,我建議這個book