2008/02/29

[Programming][Kernel] 核心同步導論

共享記憶體的應用程式環境裡面,資源必須加以保護以免發生同時存取的情況。即便是核心的本身也不能例外。保護共享資源的目的,在於防止不同的「執行緒 (threads of execution)」同時存取或修改同一個資源,彼此間互相覆蓋修改資料或存友到還沒完成改變的狀態。因為並行競爭的關係,而導致系統變得不穩定,又非常難以追蹤,所以在程式寫作的一開始注意一些細節是很重要的習慣。

保護的重要性


保護記憶體的重要性 -> 同交易 Transaction 的重要性(略)

同步鎖定


同步鎖定可以提供所需要的機制:作用方式等同家裡的門鎖。關鍵區域可以比喻做門後的房間。這個房間一次只能容許一個人(執行緒)進入,當人進入房間,它會將身後的房門鎖上,對共享資源完成更動才會打開門鎖,離開房間。上鎖期間,如果有另外一個執行緒前來敲門,也只能在門外等候,如果裡面的人還沒有完事,就沒有辦法進入。這就是同步鎖的重要性:它可以避免並行存取 (concurrency) 並且保護佇列內的資料完整。

並行存取發生的原因


在用戶層,同步的需求來自於核心排程器可以主動決定應用程式的執行權。因此在任何時刻,程序都可能會非自願地在關鍵區域中失去執行權,換另一個程序使用處理器。如果這個新來的程序稍進入同一個關鍵區域(假設兩個程序都是一般的執行緒,存取一樣的共享資源),就會引發競爭的狀況 (race condition)。當多個單執行緒的程序分享檔案,或單一程序碰到系統傳來的「信號 signals 」時也可能產生類似的問題;因為系統信號會在不定時刻以「非同步」方式發生,這種並行處理並不是真的同時發生,而是因為切割執行時間導致的狀況,我們在這裡稱之為「虛擬並行 - (pseudo-concurrency)」。

在能進行對稱多重處理 (symetrical multiprocessing) 的機器上面,兩組處理器可能同時執行同一份關鍵程式碼。這種狀況稱為「真。並行處理 (true concurrency)」。雖然這兩種並行處理的語意和成因都不相同,但兩者都會導致相同的競爭情況,需要加以設想保護的機制。

核心也有類似機制可能造成並行處理的情況,分別是:

  • 中斷 (interrupts)

  • softirqs 與 tasklets

  • 核心先佔 (kernel preemption)

  • 休眠與用戶層同步

  • 對稱式多重處理


可以避免中斷程式並行干擾的程式碼被稱作「 interrupt-safe (對中斷而言是安全的)」。可以避免在對稱多重處理的機器上面出現並行干擾的程式碼被稱作為 「SMP-safe (對 SMP 而言安全)」。可以避免在核心搶占執行權後出現並行干擾的程式碼則叫「 preempt-safe 」。

哪些資料是需要鎖定保護的呢?大多數全域性的核心資料結構會需要。有一個簡單明顯的判斷法則是:如果其它執行緒可以存取同一組的資料,就需要用到同步鎖。如果其它人也可以看見這筆資料,就鎖上它。要記得是鎖定資料而不是程式碼。

每當撰寫核心的程式碼的時候,你後

  • 資料是否有全域的屬性?另外一個執行緒是否也可以存取它?

  • 程序環境與中斷環境是否共享這些資料?是否在兩個不同的中斷處理程序中共用?

  • 如果程序存取這份資料時發生了執行權的轉移,取得執行權的新程序是否會存取相同的資料?

  • 目前的程序是否會在某些情況下休眠 (暫停)?如果會,共享資源會變成什流狀態?

  • 有沒有辦法避免其它程序錯誤地刪除 (釋放) 使用中的資源 ?

  • 如果別的處理器同時使用這個函式,會發生什麼事?

  • 你打算在程式裡頭做什麼?

[Windows] 好用的小工具: AutoHotKey

做為一個 Linux 的愛好者,轉移到 Windows 上面的時候,往往難以適應 Windows 調整快捷鍵的方式,所以 google 了一下,結果發現很多人愛用的 "Auto Hot key"。不多說,就來給一個範例說明如何使用 Auto Hot key 來...