博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux进程IPC浅析[进程间通信SystemV进程的信号量和信号量集]
阅读量:3748 次
发布时间:2019-05-22

本文共 3784 字,大约阅读时间需要 12 分钟。

Linux进程IPC浅析[进程间通信SystemV进程的信号量和信号量集]

(对共享资源主要实现互斥同步效果)

1. 进程信号量概念
2. 进程信号量集

进程信号量的概念

本质上就是共享资源的数据(非负的计数器),用来控制对共享资源的访问

用于进程间的互斥和同步
每种共享资源对应一个信号量,为了便于大量共享资源的操作引入了信号量集,可以对所有信号量一次性操作,对信号量集中所有操作可以要求全部成功,也可以要求部分成
二元信号量(信号灯)值为0和1
对信号量进程PV操作

信号量集的相关属性

#include
struct semid_ds{ struct ipc_perm sem_perm; // unsigned short sem_nsems; //信号量集中信号灯数量 time_t sem_otime; //最后一次对信号量集操作的时间 time_t sem_ctime; //最后改变的时间}

创建信号量集函数

#include
int semget(key_t key,int nsems,int flag);返回:成功返回信号量集ID,出错返回-1参数: key:用户指定的信号量集键值 nsems:信号量集 中信号量的个数 flag:IPC_CREAT,IPC_EXCL等权限

信号量集的控制函数

#include
int semctl(int semid,int semnum,int cmd,.../*union semun arg*/);union{ int val; struct semid_ds *buf; unsigned short *array;};参数: semid:信号量集ID semnum:0表示对所有信号量操作,信号量编号从0开始 val:放置获取或设置信号量集中某个信号量的值 buf:信号量集属性指针 array:放置获取或设置信号量集中所有信号量的值 cmd:通过cmd参数设定对信号量集要执行的操作 IPC_STAT 获取信号量集的属性 -->buf IPC_SET 设置信号量集的属性 -->buf IPC_RMID 删除信号量集--->buf GETVAL 返回信号量集的值 -->val SETVAL 设置semnum信号量的值 -->val GETALL 获取所有信号量的值 -->array SETALL 设置所有信号量的初始值 -->array

信号量集的操作函数

#include
int semop(int semid,struct sembuf *sops,size_t nsops);返回:成功返回0,失败返回-1用于信号量集中信号量的加减操作可以用于进程间的互斥和同步 struct sembuf{ unsigned short sem_num; short sem_op; short sem_flg; /*IPC_NOWAIT*/}参数: semid:信号量集ID sops:sembuf结构体数组指针 nsops:第二个参数中结构体数组的长度 sem_num:信号量集中信号量编号 sem_op正数为V操作,负数为P操作,0可以用于对共享资源是否已用完的测试 sem_flag:SEM_UNDO标志,表示在进程结束的时候,相应的操作将被取消,如果设置了那么进程没有释放共享资源就退出时候,内核会取代其释放

一下是对sem的一个简单的封装;

/* * =========================================================================== * *       Filename:  pv.h          PV操作,P操作表示测试消息是否到达,做-1操作,V操作发送消息,表示+1操作 *    Description:   *        Version:  1.0 *        Created:  2017年04月16日 12时27分03秒 *       Revision:  none *       Compiler:  gcc *         Author:   (),  *        Company:   * * =========================================================================== */#ifndef __PV_H#define __PV_H_//初始化信号灯/信号量的数值extern int I(int semnums,int value);//对信号量集(semid)中的信号灯(semnum)进程P操作extern void P(int semid,int semnum,int value);//对信号量集(semid)中的信号灯(semnum)进程V操作extern void V(int semid,int semnum,int value);//销毁信号量集extern void D(int semid);#endif
/* * =========================================================================== * *       Filename:  pv.c *    Description:   *        Version:  1.0 *        Created:  2017年04月16日 13时37分55秒 *       Revision:  none *       Compiler:  gcc *         Author:   (),  *        Company:   * * =========================================================================== */#include
#include
#include
#include
#include
#include
union semnu{ int val; struct semid_ds *buf; unsigned short *array;};/* * *初始化信号量集 * */int I(int semnums,int value){ int sem_id = semget(IPC_PRIVATE,semnums,IPC_CREAT | IPC_EXCL | 0777); if(sem_id < 0){ perror("create sem error"); return -1; } union semnu nu; unsigned short* array = (unsigned short*)calloc(semnums,sizeof(unsigned short)); int i; for(i = 0 ; i
0); //定义一个sembuf类型的结构体数组,防止若干个结构体变量 //对应要操作的信号量,要做的P或者V操作 //因为value是大于0的,所有-value的话,就是做P操作 struct sembuf ops[] = { {semnum,-value,SEM_UNDO}}; if(semop(semid,ops,sizeof(ops)/sizeof(struct sembuf)) < 0){ perror("semop error"); }}/* * *进行V操作(信号加操作) * */void V(int semid,int semnum,int value){ assert(value > 0); //定义一个sembuf类型的结构体数组,防止若干个结构体变量 //对应要操作的信号量,要做的P或者V操作 //因为value是大于0的,所有-value的话,就是做P操作 struct sembuf ops[] = { {semnum,value,SEM_UNDO}}; if(semop(semid,ops,sizeof(ops)/sizeof(struct sembuf)) < 0){ perror("semop error"); }}/* * 删除信号集 */void D(int semid){ if(semctl(semid,0,IPC_RMID,NULL) < 0){ perror("semctl error"); }}

以下就是关于信号量的相关的封装操作

转载地址:http://szbsn.baihongyu.com/

你可能感兴趣的文章
招新成绩统计
查看>>
webpack
查看>>
go部署
查看>>
配置swagger--go语言
查看>>
打印杨辉三角
查看>>
java中String类中常用方法
查看>>
flutter学习笔记:第一个APP应用
查看>>
哲学家进餐问题
查看>>
Python-Opencv学习总结(一):图像读取和获取图像特征
查看>>
实验十三:导出与导入
查看>>
第十五周.
查看>>
基于MVC模式的用户登录
查看>>
Java Swing搭建QQ登录界面
查看>>
Spring常用依赖及注解的使用
查看>>
解决Maven中资源过滤问题
查看>>
Springboot中解决Ajax请求跨域问题
查看>>
Keras软件安装
查看>>
cuda安装
查看>>
Anaconda3换源配置
查看>>
Unsafe.putOrderedXXX系列方法详解(数组赋值的第二种方式)
查看>>