本文共 3784 字,大约阅读时间需要 12 分钟。
(对共享资源主要实现互斥同步效果)
1. 进程信号量概念 2. 进程信号量集本质上就是共享资源的数据(非负的计数器),用来控制对共享资源的访问
用于进程间的互斥和同步 每种共享资源对应一个信号量,为了便于大量共享资源的操作引入了信号量集,可以对所有信号量一次性操作,对信号量集中所有操作可以要求全部成功,也可以要求部分成 二元信号量(信号灯)值为0和1 对信号量进程PV操作#includestruct semid_ds{ struct ipc_perm sem_perm; // unsigned short sem_nsems; //信号量集中信号灯数量 time_t sem_otime; //最后一次对信号量集操作的时间 time_t sem_ctime; //最后改变的时间}
#includeint semget(key_t key,int nsems,int flag);返回:成功返回信号量集ID,出错返回-1参数: key:用户指定的信号量集键值 nsems:信号量集 中信号量的个数 flag:IPC_CREAT,IPC_EXCL等权限
#includeint 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
#includeint 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/