字面上相似,但是本質上存在巨大的差別!請看詳細解答...
Linux信號(signal) 機制
signal,又簡稱為信號(軟中斷信號)用來通知進程發生了異步事件。
原理:
壹個進程收到壹個信號與處理器收到壹個中斷請求可以說是壹樣的。信號是進程間通信機制中唯壹的異步通信機制,壹個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什麽時候到達。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。信號機制除了基本通知功能外,還可以傳遞附加信息。
分類:
從兩個不同的分類角度對信號進行:
可靠性方面:可靠信號與不可靠信號;
與時間的關系上:實時信號與非實時信號。
部分定義轉自:blogs.com/hoys/archive/2012/08/19/2646377.html
Linux信號量(semaphore)機制
Linux內核的信號量用來操作系統進程間同步訪問***享資源。
原理:信號量在創建時需要設置壹個初始值,表示同時可以有幾個任務可以訪問該信號量保護的***享資源,初始值為1就變成互斥鎖(Mutex),即同時只能有壹個任務可以訪問信號量保護的***享資源。
壹個任務要想訪問***享資源,首先必須得到信號量,獲取信號量的操作將把信號量的值減1,若當前信號量的值為負數,表明無法獲得信號量,該任務必須掛起在該信號量的等待隊列等待該信號量可用;若當前信號量的值為非負數,表示可以獲得信號量,因而可以立刻訪問被該信號量保護的***享資源。
當任務訪問完被信號量保護的***享資源後,必須釋放信號量,釋放信號量通過把信號量的值加1實現,如果信號量的值為非正數,表明有任務等待當前信號量,因此它也喚醒所有等待該信號量的任務。
常用的信號量的API:
DECLARE_MUTEX(name)
該宏聲明壹個信號量name並初始化它的值為0,即聲明壹個互斥鎖。
DECLARE_MUTEX_LOCKED(name)
該宏聲明壹個互斥鎖name,但把它的初始值設置為0,即鎖在創建時就處在已鎖狀態。因此對於這種鎖,壹般是先釋放後獲得。
void sema_init (struct semaphore *sem, int val);
該函用於數初始化設置信號量的初值,它設置信號量sem的值為val。
void init_MUTEX (struct semaphore *sem);
該函數用於初始化壹個互斥鎖,即它把信號量sem的值設置為1。
void init_MUTEX_LOCKED (struct semaphore *sem);
該函數也用於初始化壹個互斥鎖,但它把信號量sem的值設置為0,即壹開始就處在已鎖狀態。
void down(struct semaphore * sem);
該函數用於獲得信號量sem,它會導致睡眠,因此不能在中斷上下文(包括IRQ上下文和softirq上下文)使用該函數。該函數將把sem的值減1,如果信號量sem的值非負,就直接返回,否則調用者將被掛起,直到別的任務釋放該信號量才能繼續運行。
int down_interruptible(struct semaphore * sem);
該函數功能與down類似,不同之處為,down不會被信號(signal)打斷,但down_interruptible能被信號打斷,因此該函數有返回值來區分是正常返回還是被信號中斷,如果返回0,表示獲得信號量正常返回,如果被信號打斷,返回-EINTR。
int down_trylock(struct semaphore * sem);
該函數試著獲得信號量sem,如果能夠立刻獲得,它就獲得該信號量並返回0,否則,表示不能獲得信號量sem,返回值為非0值。因此,它不會導致調用者睡眠,可以在中斷上下文使用。
void up(struct semaphore * sem);
該函數釋放信號量sem,即把sem的值加1,如果sem的值為非正數,表明有任務等待該信號量,因此喚醒這些等待者。
實例:
信號量在絕大部分情況下作為互斥鎖使用,下面以console驅動系統為例說明信號量的使用。
在內核源碼樹的kernel/printk.c中,使用宏DECLARE_MUTEX聲明了壹個互斥鎖console_sem,它用於保護console驅動列表console_drivers以及同步對整個console驅動系統的訪問。