linux信号量

博客围绕信号量展开,介绍了信号量数据结构,阐述新建信号量的方法,讲解信号量操作函数和控制函数,还给出信号量的一个例子并展示结果,涵盖了信号量相关的关键信息技术内容。

1.信号量数据结构

union semun
{
    int val;            //整形变量--信号量初值
    struct semid_ds *buf;    //semid_ds结构指针
    unsigned short *array;    //数组类型
    struct seminfo *_buf;    //信号量内部结构
};

2.新建信号量

#include<sys/types.h>
#incldue<sys/ipc.h>
#include<sys/sem.h>
int semget(key_t key,int nsems,int semflg);
key=>ftok生成的键值
nsems=>指定新的集合中创建信号量的数目
semflg=>打开信号量的方式,取值如下:
IPC_CREAT:没有该信号量就创建,有就返回该信号量的标识符
IPC_CREAT|IPC_EXCL:没有即创建,有返回-1(创建失败)

3.信号量操作函数

​

#include<sys/types.h>
#incldue<sys/ipc.h>
#include<sys/sem.h>
int semop(int semid,struct sembuf *sops,unsigned nsops);
semid操作信号量id
sops指向要在信号量集合上操作的一个数组
nsops该数组中操作的个数


struct sembuf
{
    ushort sem_num;    //    信号量编号
    short sem_op ;       //信号量的操作(P或者V)
    short sem_flg;    //信号量的操作标志
};

4.信号量控制函数

​

#include<sys/types.h>
#incldue<sys/ipc.h>
#include<sys/sem.h>
int semctl(int semid,int semnum,int cmd,....);  //信号量集合上执行控制操作
semid通过semget得到
semnum是信号量集合的索引值
cmd操作命令,取值如下:
IPC_STAT:获取某个集合的semid_ds结构
IPC_SET:设置某个集合的semid_ds结构中ipc_perm值
IPC_RMID:从内核中删除某信号
GETALL:获取集合中所有信号量的值
GETNCNT:返回当前正在等待资源的进程数目
GETPID:返回最后一次执行semop调用进程的pid
GETVAL:返回集合中某个信号量的值
GETZCNG:返回正在等待资源利用率达到百分之百的进程数目
SETALL:把集合中的所有信号量的值,设为联合体array成员包含的对应值
SETVAL:设置带个

5.信号的一个例子

#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>
#include<stdio.h>
union semun
{
        int val;
        struct semid_ds *buf;
        unsigned short *array;
};
int creatsem(key_t key,int value)

{
    union semun sem;
        int semid;
        sem.val=value;
        semid=semget(key,0,IPC_CREAT);
        if(-1==semid)
                printf("creat sem failed!\n");
        semctl(semid,0,SETVAL,sem);
        return semid;
}
int getvaluesem(int semid)
{
        union semun sem;
        int p;
        p=semctl(semid,0,GETVAL,sem);
        if(p==-1)
        {       printf("get failed!\n");
                return -999;
        }
        else return p;
}
void DESTROY(int semid)
{
        union semun sem;
        sem.val=0;
        semctl(semid,0,IPC_RMID,sem);
}
void Sem_V(int semid)
{
        struct sembuf sops={0,+1,IPC_NOWAIT};
        semop(semid,&sops,1);
}
void Sem_P(int semid)
{
        struct sembuf sops={0,-1,IPC_NOWAIT};
        semop(semid,&sops,1);
}

int main()
{
        key_t key;
        int semid;
        char i;
        int ret=0;
        int value=0;
        key=ftok("/home/18",'a');
        if(key==-1)
                printf("failed to creat key!\n");
        semid=creatsem(key,100);
        if(semid==-1)
                printf("create sem failed!\n");
        printf("the value is %d\n",value);
        for(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);
        }
        DESTROY(semid);
        return 0;
}

6.结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不要绝望总会慢慢变强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值