可以說我正在編寫一個操作系統。我不是騙子,所以我從最底層開始。過了一段時間你有進程,先發制人的調度程序和Malloc。現在你需要互斥體和信號量。從頭開始實施互斥鎖
這是一個代碼,它可以專門鎖定互斥鎖,或者專門增加或減少信號量。可以說我有這個代碼。
然後你會得到下一步:採取互斥體。讓我們說我們有兩個進程,爭取一個互斥體。在B可以觸摸它之前,進程A是第一個並且搶佔該互斥體。所以現在B必須等待。我的問題具體是關於處理等待階段。我可以看到以下選項:
- 保持過程B上的調度和每次得到一個時間片,它會檢查它是否可以鎖定互斥的時間。如果沒有,重新安排並等待下一個時間片。這種方法看起來非常完美,除了浪費CPU時間而無法執行任何操作。
- 介紹一個新進程,稱他爲Kernel。他是無所不知的人,可以接觸到所有事物。如果一個進程無法鎖定互斥鎖,它就會進入等待狀態,並且不會有更多的時間片。如果進程釋放互斥量,它會通知內核,內核將在稍後獲得時間片。在它的時間片中,它搜索等待互斥量的進程。等待此互斥鎖的優先級最高的進程將被喚醒。
- 再次假設一個進程如果無法獲得互斥量就會進入WAIT:在互斥量釋放時,釋放互斥量的進程必須通過進程列表並查看哪些進程正在等待互斥量。然後它喚醒最高優先級的那個。我不喜歡這個,因爲我真的不想讓任何進程寫訪問內存的任何部分。我計劃使用MPU來防止這種情況,檢測段錯誤等。如果我實現這種方法,我將更加難以正確地實現MPU部分。
這就是我所能看到的。我最喜歡2,但它仍然感覺像很多開銷。我很想聽聽你對這個問題的意見:你如何實現等待鎖定互斥鎖被釋放?
更多背景:我實際上是在Cortex M4 CPU上實現操作系統。我知道我將無法擊敗freeRTOS等。它關於學習體驗。
您的第三種解決方案假定互斥體釋放原語在用戶空間中工作,但如果互斥體是操作系統管理對象,則釋放功能是系統調用,它將觸發上下文切換到內核模式,內核將實際檢查等待那個互斥體的線,而不是釋放過程。所以第二種情況本質上是最準確的。 – didierc 2014-11-04 10:04:13
在鎖定和解鎖互斥鎖時,直接切換到內核的效率並不高?我只想在真正需要時切換:釋放互斥鎖並完成時間片之後。 – Cheiron 2014-11-04 11:23:02
@Cheiron - 這會帶來非常糟糕的表現。切換到內核狀態可確保等待互斥量的任何線程都已準備就緒(並且很可能正在運行),即釋放互斥量的'即時'。等待一些可能的中斷/系統調用使等待線程就緒/運行對於大多數情況下的性能來說將是災難性的,特別是在具有多核的處理器上。你正在將5us的延遲變成幾十毫秒。 – 2014-11-04 11:33:12