天天看點

linux信号量簡介(核心态)

一、什麼是信号量

    1、概念

        核心的信号量在概念和原理上與使用者态的信号量是一樣的,但是它不能在核心之外使用。

        信号量又稱為信号燈(semaphore),本質上是一種睡眠鎖。如果有一個任務試圖獲得一個不可用(已經被占用)的信号量時,信号量會将其推進一個等待隊列,然後讓其睡眠。這時處理器能重獲自由,進而去執行其他代碼。當持有的信号量可用(被釋放後),處于等待隊列中的那個任務将被喚醒,并将獲得該信号量。

        信号量一個有用的特性是它可以同時允許任意數量的鎖持有者,而自旋鎖和互斥鎖在一個時刻最多允許一個任務持有它。信号量同時允許的持有者數量可以在聲明信号量時指定。這個值稱為使用者數量(usage count)或簡單的叫做數量(count)。通常情況下,信号量和自旋鎖一樣,在一個時刻僅允許有一個鎖持有者。這時計數等于1,這樣的信号量被稱為二值信号量或者稱為互斥信号量。另一方面,初始化時也可以把數量設定為大于1的非0值。這種情況,信号量被稱為計數信号量(counting semaphore),它允許在同一時刻至多有count個鎖持有者。

    2、資料結構

struct semaphore {
	raw_spinlock_t		lock;
	unsigned int		count;
	struct list_head	wait_list;
};
           

        結構體成員說明:

        count:相當于信号量的值,大于0,資源空閑;等于0,資源忙,但沒有程序等待這個保護的資源;小于0,資源不可用,并至少有一個程序等待資源。

        wait:存放等待隊列連結清單的位址,目前等待資源的所有睡眠程序都會放在這個連結清單中。

        sleepers:存放一個标志,表示是否有一些程序在信号量上睡眠

二、信号量的使用

    1、初始化

        void sema_init (struct semaphore *sem, int val);

        void init_MUTEX (struct semaphore *sem); //将sem的值置為1,表示資源空閑

        void init_MUTEX_LOCKED (struct semaphore *sem); //将sem的值置為0,表示資源忙

    2、加鎖

        void down(struct semaphore * sem); // 可引起睡眠

        int down_interruptible(struct semaphore * sem); // down_interruptible能被信号打斷

        int down_trylock(struct semaphore * sem); // 非阻塞函數,不會睡眠。無法鎖定資源則馬上傳回

    3、解鎖

        void up(struct semaphore * sem);

三、為什麼使用信号量

    1、用于線程間的同步。

    2、當同一時刻,有多個對象需要同時持有鎖的情況下,可以使用信号量。

繼續閱讀