1.信號量的概念。 信號量的本質是一種數據操作鎖,它本?身不具有數據交換的功能,而是通過控制其他的通信資源(文件,外部設備)來實現進程間通信,它本?身只是一種外部資源的標識。信號量在此過程中負責數據操作的互斥、同步等功能。 當請求一個使用信號量來表示的資源時,進程需要先讀取信號量的值來判斷資源是否可用。大于0,資源可以請求,等于0,無資源可用,進程會進?入睡眠狀態直至資源可用。 當進程不再使用一個信號量控制的共享資源時,信號量的值+1,對信號量的值進行的增減 操作均為原子操作,這是由于信號量主要的作用是維護資源的互斥或多進程的同步訪問。 而在信號量的創建及初始化上,不能保證操作均為原子性。 2.信號量是如何工作的 由于信號量只能進?行兩種操作等待和發送信號,即P(sv)和V(sv),他們的?行為是這樣的: P(sv):如果sv的值?大于零,就給它減1;如果它的值為零,就掛起該進程的執?行 V(sv):如果有其他進程因等待sv?而被掛起,就讓它恢復運?行,如果沒有進程因等待sv?而掛 起,就給它加1. 3.相關函數 函數原型:int semget(key_t key,int nsems,int semflg); 參數解釋: key:所創建或打開信號量集的鍵值。需要是唯一的非零整數。 nsems:創建的信號量集中的信號量的個數,該參數只在創建信號量集時有效。幾乎總是取值為1. flag:調用函數的操作類型,也可用于設置信號量集的訪問權限,用或來表示。
功能描述 獲取與某個鍵關聯的信號量集標識。信號量集被建立的情況有兩種: 1.如果鍵的值是ipC_PRIVATE。 2.或者鍵的值不是IPC_PRIVATE,并且鍵所對應的信號量集不存在,同時標志中指定IPC_CREAT。 當調用semget創建一個信號量時,他的相應的semid_ds結構被初始化。ipc_perm中各個量被設置為相應 值: sem_nsems被設置為nsems所示的值; sem_otime被設置為0; sem_ctime被設置為當前時間。 函數原型:int semop( int semid, struct sembuf semoparray[], size_t nops ); 參數解釋: 參數semid是一個通過semget函數返回的一個信號量標識符 參數nops標明了參數semoparray所指向數組中的元素個數 參數semoparray是一個struct sembuf結構類型的數組指針, 結構sembuf來說明所要執行的操作,其成員如下:
其中sem_flg說明函數semop的行為。通常被設置為SEM_UNDO。它將使得操作系統跟著當前進程對這個信號量的修改情況,如果這個進程在沒有釋放該信號量的情況下終止,操作系統將自動釋放該進程持有的信號量。
函數原型:int semctl(int semid,int semnum,int cmd,…); 參數解釋: sem_id是由semget返回的信號量標識符。 sem_num與前面一個函數相同。 cmd:表示將要采取的動作。 如果有第四個參數,一般為聯合體semun,成員如下: 
信號量使用的簡單示例: 我們創建一個進程,代碼如下:
#include"head.h"#include<unistd.h>#include<sys/wait.h>int main(){ int sem_id = my_semget(1); initial(sem_id, 0); pid_t id = fork();//創建一個子進程 if (0 == id){ while(1){ //上鎖 if ( sem_p(sem_id, 0) == -1){ perror("children p error"); exit(0); } usleep(10200); printf("A"); fflush(stdout); usleep(23043); printf("A"); fflush(stdout); if ( sem_v(sem_id,0) == -1){ perror("children v error"); exit(0); } } } else{ while(1){ //上鎖 if ( sem_p(sem_id, 0) == -1){ perror("father p error"); exit(0); } usleep(10200); usleep(16200); printf("B"); fflush(stdout); usleep(33043); printf("B"); fflush(stdout); if ( sem_v(sem_id,0) == -1){ perror("father v error"); exit(0); } } int stat = 0; wait(&stat); }}在沒有信號量之前,因為有睡眠延時,系統會隨機打印A和B,如:
添加信號量之后,因為A進程在信號量上鎖后,sv值變為0,則B進程會掛起,直到A進程解鎖,則系統會有規律的打印A和B。 
新聞熱點
疑難解答