System V 信号量

一、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;
}

 

四、参考资料

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值