相對於Posix信號量,system V信號量提供了更爲豐富的操做,如Posix信號量一次只能增減1,而system V則沒有此限制;另外,能夠用一個函數(semget)建立一組(多個)信號量,而Posix信號量一次只能建立一個;所以可用其模擬Posix信號量。功能豐富的同時也決定了System V信號量的複雜性。函數
1) 相關函數:ui
頭文件:<sys/sem.h>線程
建立或打開:semgetcode
操做:semop 包含的操做有:掛出和等待(對應增減的信號量只能夠大於1)orm
控制操做:semctl,主要用於初始化信號量集中信號量的初始值、獲取相關狀態(信號量值,semid_ds結構,相關操做的線程數信息)、刪除、設置uid、gid、sem_perm.mode(讀寫權限)進程
更詳細的說明能夠查看man手冊,如man semget將獲取函數的相關說明。get
2) 要點同步
須要注意的是,因爲System V信號量的建立和初始化工做是分兩步進行的(不像Posix信號量建立和初始化是一個原子操做),這就須要相關的同步工做,確保A進程建立的信號量在被其餘進程使用前已經被初始化。it
原理:當semget建立一個新的信號量集時,其semid_ds結構的sem_otime成員保證被置爲0,所以,其餘線程在成功調用semget打開信號量後,必須以IPC_STAT命令調用semctl.而後等待sem_otime變爲非零值,這時就能夠判定信號量已被初始化。io
代碼表述以下:
#define MSG_W(0400) #define MSG_R(0200) //permission formessage queues 660 #defineSVMSG_MODE (MSG_R | MSG_W | MSG_R >> 3 | MSG_W >> 3) #define MAX_TIMES100 union senum { int val; struct semid_ds *buf; usigned short*array; }; int semid; int oflag =IPC_CREAT | IPC_EXEL | SVSEM_MODE; union senum arg; struct semid_ds seminfo; if (semid = semget(ftok(「/tmp/sem1」),1, oflag) >= 0) { // create successed, now set theinitial value arg.val = 1; semctl(semid, 0, SETVAL, arg); } else if (EEXIST== errno) { semid = semget(ftok(「/tmp/sem1」), 1,oflag); arg.buf = &seminfo; for (int i = 0; i < MAX_TIMES; i++) { semctl(semid, 0, IPC_STAT,arg); if (arg.buf->sem_otime !=0) { //here indicates initialsuccessed break; } sleep(1); } if (MAX_TIMES == i) { //aftertry MAX_TIMES, the semaphore still no been initialized } }