信号量

信号量

信号量数据结构

union semun {      /*信号量操作的联合结构*/
    int  val;      /*整型变量*/
    struct semid_ds *buf;       /*semid_ds结构指针*/
    unsigned short  *array;    /*数组类型*/
    struct seminfo  *__buf;    /*信号量内部结构*/
};


新建信号量

semget()函数用于创建一个新的信号量集合,或者访问现有的集合。

其原型如下
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);

信号量操作函数

信号量的P、V操作是通过向已经建立好的信号量(使用semget()函数),发送命令来完成的。向信号量发送命令的函数是semop()

这个函数的原型如下:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);

struct sembuf {
unsigned short  sem_num; /* semaphore index in array */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};

控制信号量参数

与文件操作的ioctl()函数类似,信号量的其他操作是通过函数semctl()来完成的。

函数semctl()的原型如下:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);

实例:

#include <stdio.h>
#include <sys/sem.h>
#include <sys/ipc.h>
typedef int sem_t;
union semun { /*信号量操作的联合结构*/
int val; /*整型变量*/
struct semid_ds *buf; /*semid_ds结构指针*/
unsigned short *array; /*数组类型*/
} arg; /*定义一个全局变量*/
sem_t CreateSem(key_t key, int value) /*建立信号量,魔数key和信号量的初始值 value*/
{
union semun sem; /*信号量结构变量*/
sem_t semid; /*信号量ID*/
sem.val = value; /*设置初始值*/

semid = semget(key,0,IPC_CREAT|0666); /*获得信号量的ID*/
if (-1 == semid) /*获得信号量ID失败*/
{
printf("create semaphore error\n");/*打印信息*/
return -1; /*返回错误*/
}

semctl(semid,0,SETVAL,sem); /*发送命令,建立value个初始值的信号量*/

return semid; /*返回建立的信号量*/
}
int Sem_P(sem_t semid) /*增加信号量*/
{
struct sembuf sops={0,+1,IPC_NOWAIT}; /*建立信号量结构值*/

return (semop(semid,&sops,1)); /*发送命令*/
}
int Sem_V(sem_t semid) /*减小信号量值*/
{
struct sembuf sops={0,-1,IPC_NOWAIT}; /*建立信号量结构值*/

return (semop(semid,&sops,1)); /*发送信号量操作方法*/
}
void SetvalueSem(sem_t semid, int value) /*设置信号量的值*/
{
union semun sem; /*信号量操作的结构*/
sem.val = value; /*值初始化*/

semctl(semid,0,SETVAL,sem); /*设置信号量的值*/
}
int GetvalueSem(sem_t semid) /*获得信号量的值*/
{
union semun sem; /*信号量操作的结构*/
return semctl(semid,0,GETVAL,sem); /*获得信号量的值*/
}
void DestroySem(sem_t semid) /*销毁信号量*/
{
union semun sem; /*信号量操作的结构*/
sem.val = 0; /*信号量值的初始化*/

semctl(semid,0,IPC_RMID,sem); /*设置信号量*/
}


int main(void)
{
key_t key; /*信号量的键值*/
int semid; /*信号量的ID*/
char i;
int value = 0;

key = ftok("/ipc/sem",'a'); /*建立信号量的键值*/

semid = CreateSem(key,100); /*建立信号量*/
for (i = 0;i <= 3;i++){ /*对信号量进行3次增减操作*/
Sem_P(semid); /*增加信号量*/
Sem_V(semid); /*减小信号量*/
}
value = GetvalueSem(semid); /*获得信号量的值*/
printf("信号量值为:%d\n",value); /*打印结果*/

DestroySem(semid); /*销毁信号量*/
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值