互斥那點事兒(上)

本年度第 10 次操做系統成員會議開始啦!程序員

一月一度的會議旨在讓你們互相交流,解決最近在工做中出現的問題,以提升整個計算機系統的工做效率。由於計算機硬件在飛速發展,而操做系統是鏈接計算機硬件和應用程序的中間層,若是故步自封,很快就會被市場淘汰,因此每位操做系統成員都很重視月度會議。服務器

此次提出問題的是進程和線程兩兄弟。測試

站在衆人前面,線程顯得有些怯場,他戳了戳進程,示意讓他先來說。進程迅速整理了下思路,挺直了身板,說:「此次的問題是在一個訂票系統裏發現的,我把這個系統的簡單邏輯畫出來了,大家一邊看我一邊說。」操作系統

「這個訂票系統分爲服務器端(server)和客戶端(client),當用戶與服務器創建鏈接時,服務器端就會創建一個新的線程來爲客戶端提供服務。訂票邏輯是這樣的:.net

單獨從這個邏輯圖上看是沒有問題的,但在實際狀況下,由於常常出現多個用戶同時搶訂一張票的情景,這種方式就可能會出錯。就像這樣:線程

在線程 A 肯定完餘票(假設是 1),但還未能成功訂票以前,線程 B 獲得了餘票數爲 1 的信息,因此 B 也認爲能夠訂票,最後致使一張票賣出去兩份。「code

內存一針見血的道:「我看這就是幾個線程執行流的衝突問題嘛,原本應該一個線程訂票操做結束後,另外一個線程才能查詢餘票。像這樣執行流交叉,確定還會出現其它意想不到的問題。」server

進程佩服的說:「誒別說,內存你說的太有道理了,我也遇到過相似的狀況,上次我和另外一個進程共享一部份內存空間,結果在使用同一個數據的時候,他把我剛寫進去的數據覆蓋掉了,害得我後面的計算全出錯了。」blog

這時,磁盤發表了他的見解:「執行流的問題,那一看就是進程調度器的鍋,怎麼非得在別人執行到關鍵步驟的時候把人家從 CPU 上趕下來!要是調度器稍微等一下子,這問題不就解決了?」隊列

進程調度器聽到這話,氣的站起來,說:「你,你怎麼憑空污人清白!何時切換進程不是由我來決定好很差?我是負責從就緒隊列選出最應該使用 CPU 的進程而已。等我開始調度的時候,那些進程就已經被操做系統撤下來了。」

操做系統補充道:「調度器說的沒錯,調度的時機是由中斷決定的。看樣子這種狀況出如今進程時間片用盡的時候,出現了時鐘中斷,而後被其餘進程搶佔了 CPU 資源。」

磁盤聽了,很差意思的說:「對不起,剛剛是我太武斷了。那照你的意思,咱們在執行到這部分代碼的時候,像這樣屏蔽時鐘中斷能夠解決這個問題了?」

操做系統搖搖頭:「「中斷禁用」這種方式確實能夠防止進程在運行這部分代碼時進行切換,可是,時鐘中斷是個人一項很是重要的功能,怎麼能隨隨便便就把控制權交給人類呢?萬一有的程序員想要他們的代碼能夠徹底佔有 CPU ,不把時鐘中斷給我開啓怎麼辦?我是不可能把這種重要權限交出去的,我要對整個系統負責。」

內存在旁邊贊同道:「除了這一方面,你還要知道,如今都是多核時代了,你即便禁用了這個 CPU 的時鐘中斷,其餘幾個核仍是能切換進程,而後訪問這些數據。磁盤啊,你明明存了那麼多文件,怎麼懂得仍是那麼少。。。」

磁盤憤憤的道:「別瞧不起我,我這就去找有沒有辦法解決這個問題!」

思考了許久的 CPU 開口了:「我來捋一捋吧,如今咱的目標是,不讓兩個進程同時執行這一段代碼——咱們把這段代碼叫作臨界區吧,換句話說,咱們須要讓進程互斥的進入臨界區。那咱們就把這段臨界區「加鎖」,」

「加鎖?這是什麼意思?」

「加鎖是個比喻,其實「」只是一個共享變量,咱們可讓它有 OPENCLOSE 這兩個值。一個進程,好比說 A,進入臨界區以前,先檢查鎖是否是 OPEN 狀態,若是是的話,就把鎖改成 CLOSE 狀態 ,這樣其餘進程在進入臨界區時,會發現鎖已經 CLOSE 了,那就讓他們循環等待 ,直到 A 出臨界區而後將鎖打開。」

內存眉頭一皺,發現事情並無這麼簡單——若是 A 發現鎖是開着的,但在 A 尚未關閉鎖以前,切換到了進程 B ,那麼 B 也會發現鎖是開着的,那麼 B 也將可以進入臨界區

想到這裏,內存把問題告訴 CPU,但 CPU 說,這對他不是問題。

原來計算機裏有一條硬件支持的指令——TSL(test and set lock,測試並加鎖),這條指令能夠保證讀字和寫字的操做「不可分割」,也就是說,在這條指令結束前,就連其餘處理器也不可能訪問該內存字。

「TSL 指令會把內存字 lock 讀到寄存器上,而後在對應的內存地址上寫入一個非零值。那咱們就能夠利用這條指令改進剛剛的加鎖的方法,就像這樣:

咱們讓進程在進入臨界區以前先調用 enter_region ,若是鎖已經被關閉(表現爲鎖非 0 ),就循環調用enter_region ,直到鎖打開,而後再進入臨界區。出臨界區以後,就調用 leave_region 把鎖打開。這樣不就解決你的問題了?「

內存點點頭,說:「這確實是一個好方法,解決了臨界區的互斥問題。」

不過操做系統不是很滿意這種解決方案:「這種解決方式須要忙等待,浪費了 CPU 的資源啊,我以爲這種 TSL 方案須要改進。」

這時候你們陷入了沉默——誰也沒有想到更好的解決方案,會議好像就此僵住了。

誰能想到一種更好的方案呢?


哈哈,我在文章裏埋了伏筆哦,你猜猜是誰找到了更好的方法呢?

補一個下篇的連接:互斥那點事兒(下)

以爲我寫的還不錯的話,就點個贊吧!

聲明:原創文章,未經受權,禁止轉載

若是本文對你有幫助,歡迎關注個人公衆號 tobe的囈語 ,帶你深刻計算機的世界~ 公衆號後臺回覆關鍵詞【計算機】有驚喜哦~

相關文章
相關標籤/搜索