其实就是学几个函数的用法:ftok(), semget() , semctl(), semop() 如果对哪个函数不熟悉就man 一下,例如man semctl()
下面是几个函数简单的实现代码,自己可以实现一下,助于理解...
sem.h:
对相应的系统函数”包装“,便于使用,例如
Ftok()对应于系统里的ftok();
//////sem.h
#include
#include
#include
#include
#include
key_t Ftok(const char *pathname, int proj_id)
{
key_t key = ftok(pathname, proj_id);
if(key == -1)
{
perror("ftok Error.\n");
exit(1);
}
return key;
}
int Semget(key_t key, int nsems, int semflg)
{
int sem_id = semget(key, nsems, semflg);
if(sem_id == -1)
{
perror("sem_get Error.\n");
exit(1);
}
return sem_id;
}
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
创建信号量:Ftok()、Semget()
这里的创建呢,信号量就相当于一个数组,然后,你创建多少个n个信号量,就把这个大的数组分成n个,下标从0到n-1,依次标识。到时候你操作哪个就写哪个下标即可。
//sem_create.c
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf(": %s pathname proj_id.\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
printf("sem_key: %x\n",sem_key);
int sem_id = Semget(sem_key, 1, IPC_CREAT|IPC_EXCL|0755);//创建1个
printf("sem_id: %d\n",sem_id);
return 0;
}
删除信号量:IPC_RMID
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf(":%s pathname proj_id\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
int sem_id = Semget(sem_key, 0, 0);
int ret = semctl(sem_id, 0, IPC_RMID);//删除0下标的信号量
if(ret == -1)
{
printf("remove fail.");
}
else
printf("remove success.");
return 0;
}
设置信号量的值:SETVAL
因为前面只创建了一个,所以就只能给下标为0的SETVAL。
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 4)
{
printf(": %s pathname proj_id sem_val.\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
int sem_id = Semget(sem_key, 0 , 0);
union semun init;
init.val = atoi(argv[3]);
int ret = semctl(sem_id, 0, SETVAL, init);//给信号量数组下标为0的SETVAL
if(ret == -1)
printf("setval Error.\n");
else
printf("setval Success.\n");
return 0;
}
获取信号量的值:GETVAL
//GetValue
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf(": %s pathname proj_id.\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
int sem_id = Semget(sem_key, 0, 0);
int ret = semctl(sem_id, 0, GETVAL);
if(ret == -1)
printf("getval Error.\n");
else
printf("getval: %d\n",ret);
return 0;
}
对semop()函数的解释,例如:
struct sembuf info[3];
info[0].sem_num = 0;
info[0].sem_op = -1;
info[0].sem_flg = 0;
info[1].sem_num = 1;
info[1].sem_op = ..;
info[1].sem_flg = 0;
info[2].sem_num = 2;
...
如果你要操作三个信号量,semop(sem_id, info, 3);即可
如果操作前两个:semop(sem_id, info, 2);
如果只是操作第二个:semop(sem_id, info[1], 1 )也可以。
对信号量进行“V“操作:可用资源数+1
//////v_sem.c
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf(": %s pathname proj_id\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
int sem_id = Semget(sem_key, 0, 0);
struct sembuf info;
info.sem_num = 0;
info.sem_op = 1;//类似于V操作
info.sem_flg = 0;
int ret = semop(sem_id, &info, 1);//对一个信号量进行操作
if(ret == -1)
printf("v Error.\n");
else
printf("v Success.\n");
return 0;
}
对信号量执行“p”操作:可用资源数 -1
///p_sem.c
#include"sem.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf(": %s pathname proj_id.\n",argv[0]);
return -1;
}
key_t sem_key = Ftok(argv[1], atoi(argv[2]));
int sem_id = Semget(sem_key, 0, 0);
struct sembuf info;
info.sem_num = 0;
info.sem_op = -1;//类似于P操作
info.sem_flg = 0;
int ret = semop(sem_id, &info, 1);
if(ret == -1)
printf("operator sem Error.\n");
else
printf("operator sem Success.\n");
return 0;
}