概述
在多線程操作中,為了保證數據的一致性,保證臨界代碼的安全性,操作系統引入了鎖機制。通過鎖機制,能夠保證多核多進程環境下,某一個時間點,只有一個線程進入臨界區代碼,從而保證臨界區中操作數據的一致性。
雖然不同的語言會提供不同的鎖接口,但是底層調用的都是操作系統提供的鎖,不同的高級語言只是在操作系統鎖機制上進行了封裝,要真正理解鎖,還是得要看操作系統是怎么實現鎖的。
鎖的本質
鎖,在內存中就是一個整型的數,不同的數值表示不同的狀態,比如0表示加鎖狀態,1表示空閑狀態。
加鎖會有一定的操作:讀內存表示鎖的變量,判斷鎖的狀態,加鎖:如果已加鎖,返回失敗;如果修改數值成功,返回成功。上面的每句話對應一句匯編代碼,但是整體上不是原子操作。
由於中斷 和多核 可能導致兩個進程同時達到鎖。
- 中斷:當線程A執行完第一步后,發生了中斷,os調度線程B,線程B也來加鎖並且加鎖成功,此時又發生中斷,OS調度線程A執行,從第二步開始,也加鎖成功。
- 多核:多個核心他們的鎖操作是沒有干擾的。
解決
核心是把以上幾個操作查值,判斷,設置等作為一個原子操作。
(一)test and set指令
該指令將讀取內存、判斷和設置值作為一個原子操作。這是一個硬件操作,不會被中斷。但是多核情況下不能解決。
(二)總線鎖定和緩存一致性
(在cpu芯片上有一個HLOCK Pin,可以通過發送指令來操作,將#HLOCK Pin電位拉低,並持續到這條指令執行完畢)cpu要執行操作時候,會發出一個 #LOCK信號,通過硬件操作,從而將總線鎖住,這樣同一總線上的其他CPU就不能通過總線來訪問內存了。這就是總線操作,但是這個開銷比較大。我們本來只是要對這步操作變成原子操作,但是現在總線鎖定把CPU和內存的通信都鎖住了。
后來用了緩存一致性。是當某塊CPU對緩存中的數據進行操作了之后,就通知其他CPU放棄儲存在它們內部的緩存,或者從主內存中重新讀取。