信号量
一、概述
1. 工作原理:
当一个进程要求使用共享内存中的资源时,系统会首先判断该资源的信号量,即统计可以访问该资源的单元个数。如果系统判断该资源的信号量大于0,进程就可以访问该资源,并且信号量要减一,当不在使用该资源时,信号量要加一,方便其他用户使用时,系统对其进程准确的判断。
注意:
如果该资源的信号量等于0,进程会进入休眠状态,等候该资源有人使用结束,信号量大于0,此时进程会被唤醒,对该资源进行访问。
2. 在一个进程通信机制中,信号量有多个信号组成,进程通过一个信号集实现同步,因此通常将信号量称之为信号量集。一个信号量集有其对应的结构(存储信号量集的各种属性),用于定义信号量集的对象,其定义如下:
sem结构体类型中定义了信号量的一些信息:
二、信号量基本操作
原码例子:点击打开链接
1. 创建信号量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key,int nsems,int semflg);
参数:
key 表示创建信号量集的键值
nesms 表示信号量集中信号量的个数,只有semget创建信号量时才有效
semflg 设置信号量的访问权限,也可以表示函数的操作类型
返回值:
成功返回与key相关的标识符,失败返回-1
2. 信号量操作函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(semid,struct sembuf* sops,unsigned nsops);
2)其中sem_flg标识有IPC_NOEWAIT和SET_UNDO参数:
semid 表示要进行操作的信号量集的标识符
sops sembuf结构体指针变量,通过此参数指定对单个信号量的操作行为
nsops 表示要操作的信号量
补充:
1)sops的数据类型为sembuf结构体,此结构体的主要元素如下:
unsigned short sem_num; //信号量值
short sem_op; //信号量的操作
short sem_flg; //操作标识
其中sem_op变量,若大于0则释放掉资源,小于0则获取共享资源
等于0表示资源已经处于使用状态
3. 信号量控制函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid,int semnum,int cmd,...);
参数
semid 表示要修改的信号量标识
semnum 标识要修改信号量集中的信号量个数
cmd 表示函数的控制类型
省略号,表示该函数参数未固定,可为三个或四个,第四个参数为arg,用于读取或存储函数返回结果,该参数是 semun的共用体类型,定义如下:
union semun
{
int val;
struct semid_ds*buf;
unsigned short*array;
struct seminfo*__buf;
};
返回值:
成功返回0,失败-1
cmd取值如下:
GETNCNT:返回值为semncnt的取值
GETPID:返回值为sempid的取值
GETVAL: 返回值为semval的取值
GETZCNT:返回值为semzcnt的取值
IPC_INFO: 返回值为内核中信号量集数组的最高索引值
SEM_INFO: 与IPC_INFO相同
SEM_STAT: 返回值为semid指定的标识符