内核维护的计数量,用于管理多进程之间共享资源
例如,由个变量n表示资源的数量,当有进程想要独占一个资源时,n的值要-1(或多个),如果n的值等于0(不够减),则进程阻塞,直到n的值可以减再被唤醒,当资源使用完毕后n的值要+1(或多个)
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, size_t nsops);
struct sembuf{
unsigned short sem_num; /* semaphore number 信号量下标 */
short sem_op; /* semaphore operation 操作*/
short sem_flg; /* operation flags 标记*/
IPC_NOWAIT //当信号量不够减时,不阻塞
SEM_UNDO //当进程结束时,信号量的值自动归还
}
int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout);
struct timespec{
__time_t tv_sec;
long int tv_nsec;
}
int semctl(int semid, int semnum, int cmd, ...);
IPC_STAT 获取信号量的属性
IPC_SET 设置信号量的属性
IPC_RMID 删除信号量的属性
IPC_INFO 获取信号量的信息
SEM_INFO 设置信号量的信息
GETALL 获取所有信号量的值
GETNCNT 获取信号量的数量
GETVAL 获取某个信号量的值
GETZCNT 返回正在等待的完全空闲的资源数目
SETALL 设置所有信号量的值
SETVAL 设置某个信号量的值
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
(Linux-specific) */
};
struct seminfo {
int semmap; /* Number of entries in semaphore
map; unused within kernel */
int semmni; /* Maximum number of semaphore sets */
int semmns; /* Maximum number of semaphores in all
semaphore sets */
int semmnu; /* System-wide maximum number of undo
structures; unused within kernel */
int semmsl; /* Maximum number of semaphores in a
set */
int semopm; /* Maximum number of operations for
semop(2) */
int semume; /* Maximum number of undo entries per
process; unused within kernel */
int semusz; /* Size of struct sem_undo */
int semvmx; /* Maximum semaphore value */
int semaem; /* Max. value that can be recorded for
semaphore adjustment (SEM_UNDO) */
};
#include
#include
#include
#include
#include
#include
int main(){
//创建信号量
int semid = semget(ftok(".",100),1,IPC_CREAT|0644);
if(0 > semid){
perror("semget");
return -1;
}
//初始化信号量的值
if(semctl(semid,0,SETVAL,5)){
perror("semctl");
return -1;
}
printf("我有5头小毛驴");
//创建进程,子进程使用信号量
for(int i=0;i<10;i++){
if(0 == fork()){
//使用信号量
struct sembuf buf = {0,-1,0};
semop(semid,&nuf,1);
printf("%u:我骑了一头小毛驴,还剩%d头小毛驴\n",getpid(),semctl(semid,0,GETVAL));
sleep(rand()%20+5);//使用
//归还信号量
buf.sem_op = 1;
semop(semid,&buf,1)
printf("%u:我还了一头小毛驴\n",getpid());
//结束进程
exit(0);
}
}
while(-1 != wait(NULL));
//删除信号量
semctl(semid,0,IPC_RMID);
}
编程模型:
进程A | 进程B | |
---|---|---|
创建信号量 | semget | 获取信号量 |
初始化信号量 | semctl | … |
加减信号量 | semop | 加减信号量 |
删除信号量 | semctl | … |
注意:信号量是用来计数的,一定要有资源对应
显示IPC对象
ipc -m
ipc -q
ipc -s
ipc -a
删除IPC对象
ipcrm -m ID
ipcrm -q ID
ipcrm -s ID