本質:計數器。當前資源個數
生命周期:隨內核
本身不具有數據交換的功能,是通過控制其他通信資源(文件、外部設備)來實現進程間通信,本身是一種外部資源的標識。在此過程中負責數據操作的互斥與同步功能。
互斥:獨占臨界資源(排他)
同步:建立在互斥基礎上(順序性)
主要作用:協調進程對共享資源的訪問,保證在任一時刻,只有一個執行線程訪問代碼的臨界區域。(其中共享內存的使用就要用到信號量)
操作:
p操作:申請資源(以信號量集為單位申請)
v操作:釋放資源
int semctl(int semid, int semnum, int cmd, ...); //系統調用它用來執行在信號量集上的控制操作
或者int semctl(int semid,int semnum,int cmd, /*union semun arg*/);
semid:信號量集IPC標識符
semnum:操作信號在信號量集中的編號(第一個信號的編號是0)
cmd中的操作:
IPC_STAT:讀取一個信號量集的數據結構semid_ds,將其存儲在semun中的buf參數中
IPC_SET:設置信號量集的數據結構semid_ds的元素ipc_perm,其值取自semun中的buf參數
IPC_RMID:將信號量集從內存中刪除
IPC_SETVAL:設置信號量集中的一個單獨的信號量的值
arg:代表一個semun的實例(它是一個聯合類型的副本,而不是一個指向聯合類型的指針)
union semun
{
int val; //value for SETVAL
struct semid_ds *buf; //buffer for IPC_STAT&IPC_SET,代表內核中使用的信號量的數據結構
unsigned short *array; //array for GETALL&SETALL,指針
struct seminfo *__buf; //buffer for IPC_INFO
};
struct semid_ds
{
struct ipc_perm sem_perm; //Ownership and permissions
time_t sem_otime; //last semop time
time_t sem_ctime; //last change time
unsigned short sem_nsems; //No. of semaphores in set
};
成功:返回一個正數
失敗:-1
int semget(key_t key, int nsems, int semflg); //獲取與某個鍵關聯的信號量集標識
nsems:創建的信號量集中的信號量的個數,該參數只在創建信號量集時有效
成功:返回信號量集IPC標識符
失敗:-1
int semop(int semid, struct sembuf * sops, unsigned nsops); //P、V操作通過調用semop函數實現,大於0表示當前可用的資源數的數量,小於0表示等待使用該資源的進程個數
semid:信號集的識別碼,通過semget獲取
sops:指向存儲信號操作結構的數組指針
struct sembuf
{
unsigned short sem_num; //semaphore number,操作信號在信號集中的編號,第一個編號是0
short sem_op; //semaphore operation
short sem_flg; //operation flags
};
sem_op:若其值為正數,該值會加到現有的信號內含值中。通常用於釋放所控資源的使用權;若其值為負數,而其絕對值又大於信號的現值,操作會阻塞,直到信號值大於或等於sem_op的絕對值。通常用於獲取資源的使用權;若其值為0,則操作將暫時阻塞,直到信號的值變為0
sem_flg:信號操作標志
IPC_NOWAIT //對信號的操作不能滿足時,semop()不會阻塞,並立即返回
IPC_UNDO //程序結束時(不論正常或異常),保證信號值會被重設為semop()調用前的值。避免程序在異常情況下結束時未將鎖定的資源解鎖,造成該資源永遠鎖定
nsops:信號操作結構的數量,恆大於或等於1
成功:0
失敗:-1