信号量

  • 信号量是一种计数器
  • 生产者消费者的典型使用

声明

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/*
用于创建一个新的信号量集合
- key:ftok()生成的键值
- nsems:指定在新的集合中创建信号量的数目
- semflsg:打开信号量的方式
*/
int semget (key_t key ,int nsems , int semflg);

/*
对信号量的P、V操作
- sembuf:将要在信号量上执行的操作
- nsops:操作个数
*/
int semop (int semid,struct sembuf *sops,unsigned nsops);

/*
用于在信号量集合上执行控制操作。
*/
int semctl (int semid,int semnum,int cmd,...);

例子:

#include <iostream>
#include <cstdio>

using namespace std;
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>


union semun {
	int val;
	struct semid_ds *buf;
	unsigned short *array;
}arg;
int CreateSem(key_t key,int value){
	union semun sem;
	int semid ;
	sem.val = value;

	semid =semget (key ,value,IPC_CREAT|0666);
	if(-1 == semid){
        cout<<"create failed"<<endl;
        return ;
    }
	semctl(semid ,0,SETVAL,sem);
	return semid;
}
int Sem_P(int semid ){
	struct sembuf sops ={0,+1,IPC_NOWAIT};
	return (semop(semid,&sops,1));

}
int Sem_V(int semid ){
	struct sembuf sops ={0,-1,IPC_NOWAIT};
	return (semop(semid,&sops,1));

}

void SetValueSem(int semid ,int value){
	union semun sem;
	sem.val =value;
	semctl(semid ,0,SETVAL,sem);

}
int GetValueSem(int semid ){
	union semun sem;
	return semctl(semid ,0,GETVAL,sem);

}
void DestroySem(int semid ){
	union semun sem;
	sem.val=0;
	semctl(semid,0,IPC_RMID,sem);
}
int main(int argc,char** argv) {
	key_t key ;
	int semid ;
	int value = 0;
	key = ftok("/ipc/sem",'a');
	semid = CreateSem(key,100);

	for(int i  =0;i<3;i++){
		Sem_P(semid);
		value = GetValueSem(semid);
		printf("%d\n",value);
		Sem_V(semid);
		value = GetValueSem(semid);
		printf("%d\n",value);
	}

	value = GetValueSem(semid);
	printf("%d\n",value);
	DestroySem(semid);

	return 0;
}