在了解和學習信號量之前,我們需要明確一點,信號量和信號不同,切勿將信號和信號量混淆,因為二者根本不是一個概念。
一、 什么是信號量?
為了防止出現因多個程序同時訪問一個共享資源而引發的一系列問題,我們需要一種方法,它可以通過生成并使用令牌來授權,在任何時刻只能有一個執行線程訪問代碼的臨界區域。臨界區域是指執行數據更新的代碼需要獨占式地執行。
信號量是一個特殊的變量,程序對其訪問都是原子操作,且只提供它等待或者發送兩種操作,也就是P操作和V操作。何為P/V操作:舉個例子,我們平常最常見也最簡單的信號形式——二值信號量。P操作則是對等待的信號量的值進行減一操作,而V操作則是對某一個信號量執行加一操作。這里我們暫時也僅針對于二值信號量來討論。
二、信號量的工作原理
信號量只能進行兩種操作等待和發送信號,即P操作和V操作,他們的行為是這樣的:
P:如果信號量的值大于零,就給它減1;如果它的值為零,就掛起該進程的執行直到
該信號量的值不為一為止。
V:如果有其他進程因等待該信號量而被掛起,就讓它恢復運行,如果沒有進程因等待該 信號量而掛起,就給它加1。
三、 POSIX信號量相關函數
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
sem_init可以設置信號量的初始值和初始狀態,sem_wait則會等待指定信號量,如果該值為0,則等待,否則對信號量的值減一并獲取資源,即P操作。sem_post則對指定信號量的值加一,即V操作。
四、 總結
信號量是一個特殊的變量,程序對其訪問都是原子操作,且只允許對它進行等待(即P(信號變量))和發送(即V(信號變量))信息操作。我們通常通過信號來解決多個進程或線程對同一資源的訪問競爭的問題。