本年度第 10 次作業系統成員會議開始啦!
一月一度的會議旨在讓大家互相交流,解決最近在作業中出現的問題,以提高整個計算機系統的作業效率,因為計算機硬體在飛速發展,而作業系統是連接計算機硬體和應用程式的中間層,如果故步自封,很快就會被市場淘汰,所以每位作業系統成員都很重視月度會議,
這次提出問題的是行程和執行緒兩兄弟,
站在眾人前面,執行緒顯得有些怯場,他戳了戳行程,示意讓他先來講,行程迅速整理了下思路,挺直了身板,說:“這次的問題是在一個訂票系統里發現的,我把這個系統的簡單邏輯畫出來了,你們一邊看我一邊說,”

“這個訂票系統分為服務器端(server)和客戶端(client),當用戶與服務器建立連接時,服務器端就會建立一個新的執行緒來為客戶端提供服務,訂票邏輯是這樣的:

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

在執行緒 A 確定完余票(假設是 1),但還未能成功訂票之前,執行緒 B 得到了余票數為 1 的資訊,所以 B 也認為可以訂票,最后導致一張票賣出去兩份,“
記憶體一針見血的道:“我看這就是幾個執行緒執行流的沖突問題嘛,本來應該一個執行緒訂票操作結束后,另一個執行緒才能查詢余票,像這樣執行流交叉,肯定還會出現其它意想不到的問題,”
行程佩服的說:“誒別說,記憶體你說的太有道理了,我也遇到過類似的情況,上次我和另一個行程共享一部分記憶體空間,結果在使用同一個資料的時候,他把我剛寫進去的資料覆寫掉了,害得我后面的計算全出錯了,”
這時,磁盤發表了他的看法:“執行流的問題,那一看就是行程調度器的鍋,怎么非得在別人執行到關鍵步驟的時候把人家從 CPU 上趕下來!要是調度器稍微等一會兒,這問題不就解決了?”
行程調度器聽到這話,氣的站起來,說:“你,你怎么憑空污人清白!什么時候切換行程不是由我來決定好不好?我是負責從就緒佇列里選出最應該使用 CPU 的行程而已,等我開始調度的時候,那些行程就已經被作業系統撤下來了,”
作業系統補充道:“調度器說的沒錯,調度的時機是由中斷決定的,看樣子這種情況出現在行程時間片用盡的時候,出現了時鐘中斷,然后被其他行程搶占了 CPU 資源,”
磁盤聽了,不好意思的說:“對不起,剛剛是我太武斷了,那照你的意思,我們在執行到這部分代碼的時候,像這樣屏蔽時鐘中斷可以解決這個問題了?”

作業系統搖搖頭:“「中斷禁用」這種方式確實可以防止行程在運行這部分代碼時進行切換,但是,時鐘中斷是我的一項非常重要的功能,怎么能隨隨便便就把控制權交給人類呢?萬一有的程式員想要他們的代碼可以完全占有 CPU ,不把時鐘中斷給我開啟怎么辦?我是不可能把這種重要權限交出去的,我要對整個系統負責,”
記憶體在旁邊贊同道:“除了這一方面,你還要知道,現在都是多核時代了,你即使禁用了這個 CPU 的時鐘中斷,其他幾個核還是能切換行程,然后訪問這些資料,磁盤啊,你明明存了那么多檔案,怎么懂得還是那么少,,,”
磁盤憤憤的道:“別瞧不起我,我這就去找有沒有辦法解決這個問題!”
思考了許久的 CPU 開口了:“我來捋一捋吧,現在咱的目標是,不讓兩個行程同時執行這一段代碼——我們把這段代碼叫做臨界區吧,換句話說,我們需要讓行程互斥的進入臨界區,那我們就把這段臨界區「加鎖」,”
“加鎖?這是什么意思?”
“加鎖是個比喻,其實「鎖」只是一個共享變數,我們可以讓它有 OPEN 和 CLOSE 這兩個值,一個行程,比如說 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 方案需要改進,”
這時候大家陷入了沉默——誰也沒有想到更好的解決方案,會議好像就此僵住了,
誰能想到一種更好的方案呢?
哈哈,我在文章里埋了伏筆哦,你猜猜是誰找到了更好的方法呢?
覺得我寫的還不錯的話,就點個贊吧!
宣告:原創文章,未經授權,禁止轉載
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/67335.html
標籤:C
上一篇:C++之救濟金發放問題
