相对于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 } }