一、System V 信号量
1.信号量linux命令
显示:
ipcs -a 显示所有共享内核对象
ipcs -s 显示信号量 s = semphore
删除:
ipcrm -s ID 删除信号量
二、主要函数应用
1. 函数原型:
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);
参数:
- key:信号集的名字
- nsems:信号集中信号量的个数
- semflg:由九个权限标志构成,它们的用法和创建文件时用的mode模式标志是一样的。
2. 函数原型:
#include <sys/sem.h>
int semctl(int semid. int semnum, int cmd, ..../*union semun arg*/);
参数:
- semid:由semget返回的信号集标识码
- semnum:信号集中信号量的序号
- cmd:将要采取的动作(有三个可能取值)
- 最后一个参数根据命令不同而不同
cmd:
命令 | 说明 |
---|---|
SETVAL | 设置信号量集中信号量的计数值 |
GETVAL | 获取信号集中的信号量的计数值 |
IPC_STAT | 对此集合取semid_ds结构,并存储在arg.buf指向的结构中 |
IPC_SET | 在进程有足够权限的前提下,把信号集中的当前关联值设置为semid_ds 数据结构中给出的值 |
IPC_RMID | 删除信号集 |
3. 函数原型:
#include <sys/sem.h>
int semop(int semid, struct sembuf semoparray[], size_t nops);
参数:
- semid:是该信号集量的标识码ID,也是semget函数的返回值。
- sops:是一个指向结构体的指针
- nsops:操作的信号量的个数
三、程序清单
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define ERR_EXIT(m) do { perror(m), exit(EXIT_FAILURE); }while(0)
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int sem_creat(key_t key)
{
int semid;
semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
if (semid == -1)
ERR_EXIT("semget");
return semid;
}
int sem_open(key_t key)
{
int semid;
semid = semget(key, 0, 0);
if (semid == -1)
ERR_EXIT("semget");
return semid;
}
int sem_setval(int semid, int val)
{
union semun su;
su.val = val;
int ret;
ret = semctl(semid, 0, SETVAL, su);
if (ret == -1)
ERR_EXIT("sem_setval");
return 0;
}
int sem_getval(int semid)
{
int ret;
ret = semctl(semid, 0, GETVAL, 0);
if (semid == -1)
ERR_EXIT("sem_getval");
printf("current val is %d\n", ret);
return ret;
}
int sem_d(int semid)
{
int ret;
ret = semctl(semid, 0, IPC_RMID, 0);
if (ret == -1)
ERR_EXIT("semctl");
return 0;
}
int sem_p(int semid)
{
struct sembuf sb = { 0, -1, 0 };
int ret;
ret = semop(semid, &sb, 1);
if (ret == -1)
ERR_EXIT("semop");
return ret;
}
int sem_v(int semid)
{
struct sembuf sb = { 0, 1, 0 };
int ret;
ret = semop(semid, &sb, 1);
if (ret == -1)
ERR_EXIT("semop");
return ret;
}
int sem_getmode(int semid)
{
union semun su;
struct semid_ds sem;
su.buf = &sem;
int ret = semctl(semid, 0, IPC_STAT, su);
if (ret == -1)
ERR_EXIT("semctl");
printf("currcnt pcrmissions id %o\n", su.buf->sem_perm.mode);
return ret;
}
int sem_setmode(int semid, char *mode)
{
union semun su;
struct semid_ds sem;
su.buf = &sem;
int ret = semctl(semid, 0, IPC_STAT, su);
if (ret == -1)
ERR_EXIT("semctl");
printf("cuttent permissions is %o\n", su.buf->sem_perm.mode);
sscanf(mode, "%o", (unsigned int*)&su.buf->sem_perm.mode);
ret = semctl(semid, 0, IPC_SET, su);
if (ret == -1)
ERR_EXIT("semctl");
printf("permissins updated...\n");
}
void usage(void)
{
fprintf(stderr, "usage\n");
fprintf(stderr, "semtool -c\n");
fprintf(stderr, "semtool -d\n");
fprintf(stderr, "semtool -p\n");
fprintf(stderr, "semtool -v\n");
fprintf(stderr, "semtool -s <val>\n");
fprintf(stderr, "semtool -q\n");
fprintf(stderr, "semtool -f\n");
fprintf(stderr, "semtool -m <mode>\n");
}
int main(int argc, char *argv[])
{
int opt;
opt = getopt(argc, argv, "cdpvs:gfm:");
if (opt == '?')
exit(EXIT_FAILURE);
if (opt == -1)
{
usage();
exit(EXIT_FAILURE);
}
key_t key = ftok(".", 's');
int semid;
switch (opt)
{
case'c':
sem_creat(key);
break;
case'p':
semid = sem_open(key);
sem_p(semid);
sem_getval(semid);
break;
case'v':
semid = sem_open(key);
sem_v(semid);
sem_getval(semid);
break;
case'd':
semid = sem_open(key);
sem_d(semid);
break;
case's':
semid = sem_open(key);
sem_setval(semid, atoi(optarg));
break;
case'g':
semid = sem_open(key);
sem_getval(semid);
break;
case'f':
semid = sem_open(key);
sem_getmode(semid);
break;
case'm':
semid = sem_open(key);
sem_setmode(semid, argv[2]);
break;
}
return 0;
}
四、参考资料