在這里只和大家分享下有關System V信號量。
System V通過定義計數信號量集來對信號量的操作,計數信號量集是一個或多個信號量構成一個集合,其中每個都是計數信號量。對于系統中的每個信號量集,內核維護一個如下的信息結構,它定義在頭文件中。
struct semid_ds{
struct ipc_perm sem_perm; /* operation permission struct */
struct sem *sem_base; /* ptr to array of semaphores in set */
uishort sem_nsems; /* #of semaphores in set */
time_t sem_otime; /* time of last semop() */
time_t sem_ctime; /* time of creation or last IPC_SET */
};
成員struct sem結構如下:
struct sem{
ushort_t semval; /* semaphore value , nonnegative */
short sempid; /* PID of last successful semop(), SETVAL, SETALL */
ushort_t semncnt; /* awaiting semval > current value */
ushort_t semzcnt; /* awaiting semval = 0 */
};
#include int semget(key_t key, int nsems, int oflag);
該函數成功返回時,其返回值是一個稱為信號量標識符的整數,semop和semctl使用它。出錯則返回-1。
nsems參數指定集合中的信號量數。如果我們創建一個新的信號量集,而只是訪問一個已存在的集合,那就可以把該參數指定為0。一旦創建完一個信號量集,我們就不能改變其中的信號量數。
oflag值是一些權限值的組合,如果是創建一個信號量集,那么得在此oflag的基礎上或上O_CREAT或者是O_CREAT|O_EXCL。
此函數不可以對創建的信號量集中的信號量進行初始化,對信號量的初始化是通過另外的一個函數semctl進行的。
通過semctl函數對信號量集中的信號量進行初始化。
#include int semctl(int semid, int semnum, int cmd, …./* union semun arg*/);
semid標識其操作待控制的信號量集。
semnum標識該信號量集內的某個成員(0, 1等待,直到nsems -1)。semnum值僅僅用于GETVAL、SETVAL、GETNCNT、GETZCNT和GETPID命令。
第四個參數是可選的,取決于第三個參數cmd。union semnu結構如下:
union semnu{
int val; /* used for SETVAL only */
struct semid_ds *buf; /* used for IPC_SET and IPC_STAT */
ushort *array; /* used for GETALL and SETALL */
};
這個聯合體并沒有出現在任何頭文件中,因而必須由應用程序聲明。
第三個參數cmd可以取以下值:
GETVAL 把semval的當前值作為函數返回值返回。
SETVAL 把semval值設置為arg.val。如果操作成功,那么相應信號量在所有進程是的信號
量調整值(semadj)將被置為0。
IPC_RMID 把由semid指定的信號量集從系統中刪除掉。
IPC_SET 設置所指定信號量集的semid_ds結構中的某些成員。
IPC_SET R 返回所指定信號量集當前的semid_ds結構。