目錄
本學筆記基於zephyr 工程版本 2.2.99,主機環境爲ubuntu18.04,開發平臺 nrf52840dk_nrf52840
摘要
互斥鎖(mutexes )一般用於資源訪問的互斥,簡單的互斥通過信號量去做也可以,但是在基於優先級調度的實時系統使用信號量做資源保護,容易引發優先級翻轉的的問題,而互斥鎖會動態的調整調用線程的優先級,從而避免了優先級翻轉的問題。
1 概念
任意數量的互斥鎖可以被定義,引用互斥鎖時使用的是內存地址,所以可以隨便定義。
互斥鎖有以下關鍵屬性:
lock count, 代表了在線程中被上鎖的次數,如果這個數爲0,代表已經是非鎖定狀態。
owning thread, 代表了哪個線程給這個互斥鎖上鎖。
當有多個線程,訪問同一個公共資源時(比如讀寫全局變量),爲了實現互斥訪問,可以定義一個互斥鎖來保護這個資源,當訪問資源時,需要首先獲取互斥鎖。當這個互斥鎖被其他線程上鎖後,當前訪問這個互斥鎖的線程可以選擇等待這個互斥鎖被解鎖。任意數量的線程可以同時等待給互斥鎖上鎖, 當互斥鎖可用時,優先級最高等待時間最長的線程可以優先訪問。因爲訪問的是公共資源,所以上鎖後,需要儘量短的時間使用這個資源。否則,長時間被上鎖後,其他線程也需要等待相同的時間。上鎖和解鎖一般是成對出現的,儘量不要嵌套,否則會引起死鎖,死鎖的問題是很不好排查的。
2 實現
2.1 定義互斥鎖
使用struct k_mutex類型定義一個互斥鎖變量。互斥鎖必須在使用之前通過k_mutex_init()進行初始化。
下面的代碼定義並初始化互斥鎖:
struct k_mutex my_mutex;
k_mutex_init(&my_mutex);
同樣,也可以使用K_MUTEX_DEFINE宏,在編譯時定義和初始化互斥鎖。
K_MUTEX_DEFINE(my_mutex);
2.2 上鎖
調用k_mutex_lock()給一個互斥鎖上鎖。
下面的代碼表示給一個互斥鎖上鎖,K_FOREVER表示當鎖被其他線程鎖定時,當前線程一直睡眠,知道互斥鎖變爲可用:
k_mutex_lock(&my_mutex, K_FOREVER);
也可以不一值等待,僅等待一段時間,下面代碼表示鎖不可用時等待100ms:
if (k_mutex_lock(&my_mutex, K_MSEC(100)) == 0) {
/* mutex successfully locked */
} else {
printf("Cannot lock XYZ display\n");
}
2.3 解鎖
調用k_mutex_unlock()解鎖互斥鎖,
k_mutex_unlock(&my_mutex);
3 參考鏈接
https://docs.zephyrproject.org/latest/reference/kernel/synchronization/mutexes.html#id2