System V 信號量使用相關函數
阿新 • • 發佈:2018-10-04
mode 可選參數 訪問 訪問權限 給定 素數 per 分配 絕對值
System V 信號量
在提到Posix 信號量時,指的是二值信號量或計數信號量,而System V信號量指的是入了計數信號量集
二值信號量:其值為0或1,類似於互斥鎖,資源被鎖住時為0,資源可用為1
計數信號量:其值在0和某個限制值之間的信號量,信號量的值就是可用資源數
計數信號量集:一個或多個信號量構成一個集合,集合中每個元素都是計數信號量(每個集合的信號量數存在一個限制)
semid_ds結構:
內核為每個信號量集維護的信息結構
#include <sys/sem.h> struct semid_ds{ struct ipc_perm sem_perm; // 當前信號量的訪問權限struct sem *sem_base; // 內核用於維護某個給定信號量的一組值的內部數據結構 ushort sem_nsems; // 集合中信號量的數目 time_t sem_otime; // 最近一次執行semop()的時間 time_t sem_ctime; // 集合創建時間或最近一次IPC_SET的時間 }; struct sem{ ushort_t semval; // 信號量實際值 short sempid; // 對信號量值執行最後一次操作的進程的進程IDushort_t semncnt; // 等待信號量值增長的進程數 ushort_t semzcnt; // 等待信號量值變為0的進程數 };
semget()函數:
#include <sys/sem.h> // 創建一個信號量集或訪問一個已存在的信號量集 // 成功返回非負信號量標識符,出錯返回-1 int semget(key_t key, int nsems, int oflag); // key: IPC 鍵 // nsems:指定集合中信號量數 // oflag:SEM_R(讀)和SEM_A(改)的組合,還可以按位與IPC_CREAT或IPC_CREAT|IPC_EXCL
semop()函數:
#include <sys/sem.h> // 對信號量集中一個或多個信號量進行操作 // 成功返回0,出錯返回-1 int semop(int semid, struct sembuf *opsptr, size_t nops); // semid:由semget()函數返回的信號量標識符 // nops: 指出opsptr指向的結構數組的元素數量 // opsptr:指向一個如下的數組 struct sembuf{ short sem_num; // 信號量集中信號量的索引值:0, 1, ... , nsems-1(sem_base[sem_num], 指定對某個特定信號量進行操作) short sem_op; // 指定對特定信號量的操作 short sem_flg; // 操作標誌,0, IPC_NOWAIT、SEM_UNDO }; // sembuf結構內元素的排列順序並不保證如上述那樣,只保證該結構中有上述三個元素 // sembuf結構不能靜態初始化(struct sembuf value = {0, 0, 0} // Error) // sembuf結構需要運行時初始化(struct sembuf value; value.sem_num = 0; ...) // sem_op:每個特定的操作有sem_op確定,它可以是負數、0、正數 // sem_op為正數時,其值加到semval(信號量當前值)上,對應於釋放信號量控制的資源 // 如果指定了SEM_UNDO標誌,就從相應信號量的semadj(所指定信號量針對調用進程的調整值)減去sem_op // sem_op為0,調用者等待semval變為0,如果semval已經為0,則立即返回 // sem_op為負數,調用者希望等待semval變為大於或等於sem_op的絕對值,這對應於分配資源
semctl()函數:
#include <sys/sem.h> // 對一個信號量執行各種控制操作 // 成功返回非負值,出錯返回-1 int semctl(int semid, int semnum, int cmd, ... /* union semun arg */); // semid: 標識其操作待控制的信號量集 // semnum: 標識信號量集內的某個成員(sem_base[sem_num]) // cmd:可選值如下(除非另外說明,操作成功函數返回值為0,出錯為-1) // GETVAL:將semval的當前值作為函數返回值返回 // SETVAL:將semval設為arg.val(若操作成功,那麽相應信號量的semadj被設為0) // GETPID:將sempid的當前值作為函數返回值返回 // GETNCNT:將semncnt(等待semval變為大於其當前值的線程數)的當前值作為函數返回值返回 // GETZCNT:將semzcnt(等待semval變為0的線程數)的當前值作為函數返回值返回 // GETALL:返回指定信號量集內每個成員的semval值(這些值通過arg.array指針返回) // SETALL:設置指定信號量集內每個成員的semval值(這些值通過arg.array指針傳遞) // IPC_RMID:將由semid指定的信號量集從系統刪除 // IPC_SET:設置指定信號量集的semid_ds結構中的sem_perm.uid、sem_perm.gid、sem_perm.mode,這些值由arg.buf參數指向的結構中的相應成員指定 // IPC_STAT:返回指定信號量集當前的semid_ds結構(通過arg.buf) // arg: 可選參數,根據 cmd 參數而定 union semun{ int val; struct semid_ds *buf; ushort *array; };
System V 信號量使用相關函數