描述
以一個停車場的運作為例。簡單起見,假設停車場隻有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛直接進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,打開車攔,放入外面的一輛進去,如果又離開兩輛,則又可以放入兩輛,如此往複。
在這個停車場系統中,車位是公共資源,每輛車好比一個線程,看門人起的就是信号量的作用。
分類
整型信号量(integer semaphore):信号量是整數
記錄型信号量(record semaphore):每個信号量s除一個整數值s.value(計數)外,還有一個進程等待隊列s.L,其中是阻塞在該信号量的各個進程的标識
二進制信号量(binary semaphore):隻允許信号量取0或1值
每個信号量至少須記錄兩個信息:信号量的值和等待該信号量的進程隊列。它的類型定義如下:(用類PASCAL語言表述)
semaphore=record
value:integer;
queue:^PCB;
end;
其中PCB是進程控制塊,是操作系統為每個進程建立的數據結構。
s.value>=0時,s.queue為空;
s.value<0時,s.value的絕對值為s.queue中等待進程的個數;
特性
抽象的來講,信号量的特性如下:信号量是一個非負整數(車位數),所有通過它的線程/進程(車輛)都會将該整數減一(通過它當然是為了使用資源),當該整數值為零時,所有試圖通過它的線程都将處于等待狀态。在信号量上我們定義兩種操作:Wait(等待)和Release(釋放)。當一個線程調用Wait操作時,它要麼得到資源然後将信号量減一,要麼一直等下去(指放入阻塞隊列),直到信号量大于等于一時。Release(釋放)實際上是在信号量上執行加操作,對應于車輛離開停車場,該操作之所以叫做“釋放”是因為釋放了由信号量守護的資源。
操作方式
對信号量有4種操作(include):
1.初始化(initialize),也叫做建立(create)int sem_init(sem_t *sem, int pshared, unsigned int value);
2.等信号(wait),也可叫做挂起(suspend)int sem_wait(sem_t*sem);
3.給信号(signal)或發信号(post)int sem_post(sem_t*sem);
4.清理(destroy)int sem_destory(sem_t*sem);
創建
同共享内存一樣,系統中同樣需要為信号量集定制一系列專有的操作函數(semget,semctl等)。系統命令ipcs可查看當前的系統IPC的狀态,在命令後使用-s參數。使用函數semget可以創建或者獲得一個信号量集ID,函數原型如下:
#include
int semget(key_t key,int nsems,int flag);
函數中參數key用來變換成一個标識符,每一個IPC對象與一個key相對應。當新建一個共享内存段時,使用參數flag的相應權限位對ipc_perm結構中的mode域賦值,對相應信号量集的shmid_ds初始化的值如表1所示。
shmid_ds結構初始化值表參數nsems是一個大于等于0的值,用于指明該信号量集中可用資源數(在創建一個信号量時)。當打開一個已存在的信号量集時該參數值為0。函數執行成功,則返回信号量集的标識符(一個大于等于0的整數),失敗,則返回–1。函數semop用以操作一個信号量集,函數原型如下:
#include
int semop(int semid,struct sembuf semoparray[],size_t nops);
函數中參數semid是一個通過semget函數返回的一個信号量标識符,參數nops标明了參數semoparray所指向數組中的元素個數。參數semoparray是一個struct sembuf結構類型的數組指針,結構sembuf來說明所要執行的操作,其定義如下:
struct sembuf{unsigned short sem_num;short sem_op;short sem_flg;}
在sembuf結構中,sem_num是相對應的信号量集中的某一個資源,所以其值是一個從0到相應的信号量集的資源總數(ipc_perm.sem_nsems)之間的整數。sem_op指明所要執行的操作,sem_flg說明函數semop的行為。sem_op的值是一個整數,如表2所示,列出了詳細sem_op的值及所對應的操作。
sem_op值詳解
發展史
1965年,荷蘭學者Edsger Dijkstra提出的信号量(Semaphores)機制是一種卓有成效的進程同步工具,在長期廣泛的應用中,信号量機制得到了極大的發展,它從整型信号量經記錄型信号量,進而發展成為“信号量集機制”,現在信号量機制已經被廣泛的應用到單處理機和多處理機系統以及計算機網絡中。