C语言用信号量进行pv操作

news/2025/2/13 5:56:22/

一、获取信号量

用semget()函数获取信号量,其中semget()函数中所需传的参数如下:

semget(key_t key , int nsems, semflg);

参数解释:

1、其中key可以通过ftok() 函数进行获取,ftok函数所需传入的参数为①文件路径②一个八位的整数

2、nsems是所需创建的信号量的个数,如果只是访问已存在的信号量集合,可以将此参数设置为0。

3、semflg是一个标志参数,用于指定创建或访问信号量集合的方式,常用的标志有:

IPC_CREAT:如果指定的键值对应的信号量集合不存在,则创建一个新的信号量集合。

IPC_EXCL:与IPC_CREAT同时使用,如果指定的键值对应的信号量集合已经存在,则返回错误。

0666:用于指定信号量集合的权限,表示允许所有用户读写信号量集合,这里也可以是填其它权限,如0664等,不一定是0666

具体实现:

int sem_creat(key_t key, int nsems)
{int semid = semget(key, nsems, 0664|IPC_CREAT);//创建信号量if(semid < 0){  //通过返回值判断信号量是否创建成功,小于零则创建失败,打印一下错误信息并退出perror("semget");exit(0);    }return semid;
}

二、初始化信号量

用semctl来初始化信号量,其中semctl函数所需传入的参数如下:

int semctl(int semid, int semnum, int cmd, ...)

参数解释: 

1、semid:信号量集合的标识符,通过smget函数获取(也就是上一步获取信号量的时候得到的)。

2、semnum:要操作的信号量在集合中的索引(也就是要初始化哪一个信号量),对于一个信号量集合可以有多个信号量,而semnum指定了要操作的具体信号量

3、cmd:指定要执行的命令,可以是以下几种之一:

①、GETVAL:获取指定信号量的当前值。

②、SETVAL:设置指定信号量的值。

③、IPC_RMID:删除信号量集合。

④、IPC_STAT:获取信号量集合的状态信息。

⑤、IPC_SET:设置信号量集合的状态信息。

⑥、GETALL:获取所有信号量的当前值。

⑦、SETALL:设置所有信号量的值。

4、....:表示可变参数,根据不同的命令有不同的使用方式,需要注意的是。semctl函数的第四个参数arg的具体含义取决于使用命令和使用方式(也就是根据第三个参数来的),对于某些命令,arg是一个整数值,而对于其它命令,arg是一个指向union semun结构体的指针。在使用semctl函数时,需要根据具体的需求和命令来确定如何使用这个参数。

具体实现:

void init_sem(int semid,int semnum,int val)//初始化需要传semid和初始化哪个信号量,还有初始化的值
{int ret;union semun sem;//这个是根据第三个参数来的,semun联合体中有好多种数据类型sem.val = val;ret = semctl(semid,semnum,SETVAL,sem);//这里用的是SETVAL,所以要传第四个参数,也就是你要初始化的值if(ret < 0)//判断是否初始化成功{perror("semctl");exit(0);}
}

注意: union semun联合体(也叫共用体)需要我们自己去实现,大概的样子长这样:

union semun {int val;                  // 设置信号量的初始值或获取当前值struct semid_ds *buf;     // IPC_STAT 或 IPC_SET 时使用unsigned short *array;    // GETALL 或 SETALL 时使用
};

三、进行p操作(加锁操作)

用semop函数来进行加锁操作,semop函数传入的参数如下:

 int semop(int semid, struct sembuf *sops, size_t nsops);

参数解释: 

1、semid:是一个信号量集标识符,用于指定要操作的信号量集。在使用semget函数创建信号量集后,会返回该标识符。

2、sops:是一个指向sembuf结构体数组的指针,每个sembuf结构体表示对一个信号量的操作(也就是通过结构体来设置信号量当前的状态)。

sembuf结构体的定义如下:

struct sembuf {unsigned short sem_num;  // 信号量在信号量集中的索引short sem_op;            // 信号量的操作short sem_flg;           // 操作标志
};

其中

sem_num是要操作的信号量在信号量集中的索引,从0开始计数

sem_op:是对信号量的操作,可以是正整数、负整数或零。

·  正整数表示将信号量的值增加相应的数量。

·  负整数表示将信号量的值减少相应的数量。

·  零表示等待信号量变为零。

 sem_flg是操作标志,用于指定操作的行为,常见的取值有:

  • SEM_UNDO:如果进程退出时仍然持有该信号量,则会自动释放。
  • IPC_NOWAIT:如果无法立即执行操作,则函数会立即返回,并设置错误码为EAGAIN

3、nsops:表示sembuf结构体数组中元素的数量,即要进行操作的信号量的个数。

具体实现:

void sem_p(int semid,int semnum,size_t nsops)
{struct sembuf sops;sops.sem_num = semnum;//设置要操作哪个信号量sops.sem_op = -1;//设置信号量要执行的操作,-1是上锁的操作,锁-1sops.sem_flg = SEM_UNDO;//防止死锁‘int ret = semop(semid,&sops,nsops);if(ret < 0)//判断是否执行成功{perror("semop-p");exit(0);}    
}

四、进行v操作(解锁操作) 

进行v操作也是用的semop函数,只是传的参数不同,sops.sem_op = 1。

具体实现:

void sem_v(int semnum,size_t nsops)
{struct sembuf sops;sops.sem_num = semnum;sops.sem_op = +1;//与p操作不同的地方sops.sem_flg = SEM_UNDO;int ret = semop(semid,&sops,nsops);if(ret < 0){perror("semop-v");exit(0);}
}

五、释放信号量

释放信号量也可以用semctl()函数,只是传的参数有变化

具体实现:

void sem_destroy(int semid)
{int ret = semctl(semid,-1,IPC_RMID);if(ret < 0){perror("semctl-rmid");exit(0);}
}


http://www.ppmy.cn/news/1015003.html

相关文章

Numpy矩阵拼接

一、矩阵拼接一、矩阵拼接 numpy矩阵拼接常用方法&#xff1a; np.append(arr,values,axis) np.concatenate(arrays,axis,outNone) np.stack(arrays,axis,outNone) np.hstack(tup) np.vstack(tup) ① np.append(arr,values,axis) 支持数组和数组或数组和数的拼接&#xff0c;不…

vue3集成echarts最佳实践

安装 echarts npm install echarts --save 两种引用方式 非虚拟 dom import * as echarts from echarts;var chartDom document.getElementById(mychart); var myChart echarts.init(chartDom); var option;option {title: {text: Referer of a Website,subtext: Fake Da…

【Matlab】RBF神经网络遗传算法(RBF-GA)函数极值寻优——非线性函数求极值

上一篇博客介绍了GRNN神经网络遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值&#xff0c;神经网络用的是RBF神经网络&#xff0c;RBF神经网络和GRNN神经网络有相似之处。本篇博客将GRNN神经网络替换成RBF神经网络&#xff0c;希望能帮助大家快速入门RBF网络。 1.背景条件…

GWJDN-400型2MHZ自动平衡高温介电温谱仪

GWJDN-400型2MHZ自动平衡高温介电温谱仪 关键词&#xff1a;介电常数&#xff0c;高温介电&#xff0c;自动平衡 主要功能&#xff1a; 材料介电常数测试仪 半导体材料的介电常数、导电率和C-V特性液晶材料:液晶单元的介电常数、弹性常数等C-V特性 性能特点: 温度&#xf…

Spring IoC (控制反转)

IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;是一个重要的面向对象编程法则。 Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化&#xff0c;控制对象与对象之间的依赖关系。…

nacos升级开启鉴权后,微服务无法连接的解决方案

版本&#xff1a; 软件版本号备注spring boot2.2.5.RELEASEspring-cloudHoxton.SR3spring-cloud-alibaba2.2.1.RELEASEnacos2.0.1从1.4.2版本进行升级。同时作为注册中心和配置中心 一、升级nacos版本&#xff0c;开启鉴权 1.在application.properties配置文件开启鉴权&…

C# 有效的字母异位词

242 有效的字母异位词 给定两个字符串 和 &#xff0c;编写一个函数来判断 是否是 的字母异位词。stts 注意&#xff1a;若 和 中每个字符出现的次数都相同&#xff0c;则称 和 互为字母异位词。stst 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输…

【C++】STL——priority_queue优先级队列的介绍和使用、priority_queue的其他成员函数使用

文章目录 1.priority_queue的介绍2.priority_queue的使用&#xff08;1&#xff09;priority_queue() 构造一个空的优先级队列 &#xff08;2&#xff09;priority_queue(first,last) 通过迭代器构造优先级队列&#xff08;3&#xff09;empty( )检测优先级队列是否为空&#x…