系统编程之信号量

系统编程之信号量



在这里插入图片描述

1.信号量不同于while循环,while循环会占有cpu资源,而信号量则进入了休眠状态
2.信号量被删除后,所有等待信号量的资源的进程都将忽略等待继续运行,信号量只有一个但成员可以多个



如何使用信号量:

使用ipcs -s查看系统信号量
在这里插入图片描述
1.创建健值ftok()


2.创建信号量:功能 获取信号量的 ID

  • 头文件
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
  • 函数原型
int semget(key_t key, int nsems, int semflg);
参数分析
key信号量的键值
nsems信号量元素的个数
semflg
IPC_CREAT如果 key 对应的信号量不存在,则创建之
IPC_EXCL如果该 key 对应的信号量已存在,则报错
mode信号量的访问权限(八进制,如 0644)
  • 返回值
    成功 该信号量的 ID
    失败 -1


3.信号量初始化:

  • 头文件
    #include <sys/sem.h>
  • 函数原型
int semctl(int semid, int semnum, int cmd, ...);
参数分析
semid信号量 ID
semnum信号量元素序号(数组下标)
cmd操作的命令如下
IPC_STAT获取属性信息
IPC_SET设置属性信息
IPC_RMID立即删除该信号量,参数 semnum 将被忽略
IPC_INFO获得关于信号量的系统限制值信息
SEM_INFO获得系统为共享内存消耗的资源信息
SEM_STAT同 IPC_STAT,但 shmid 为该 SEM 在内核中记录所有 SEM 信息的数组的下标,因此通过迭代所有的下标可以获得系统中所有 SEM 的相关信息
GETALL返回所有信号量元素的值,参数 semnum 将被忽略
GETNCNT返回正阻塞在对该信号量元素 P 操作的进程总数
GETPID返回最后一个队该信号量元素操作的进程 PID
GETVAL返回该信号量元素的值
GETZCNT返回正阻塞在对该信号量元素等零操作的进程总数
SETALL设置所有信号量元素的值,参数 semnum 将被忽略
SETVAL设置该信号量元素的值,赋予初始值等于第四个参数

第四个参数是一个联合体:

 union semun {
               int              val;    //SETVAL命令使用
               struct semid_ds *buf;    //IPC_STAT, IPC_SET 使用
               unsigned short  *array;  //GETALL, SETALL 使用
               struct seminfo  *__buf;  //IPC_INFO使用
           };

使用 IPC_STAT 和 IPC_SET 需要用到以下属性信息结构体:

struct semid_ds
{
	struct ipc_perm sem_perm; /* 权限相关信息 */
	time_t sem_otime; /* 最后一次 semop( )的时间 */
	time_t sem_ctime; /* 最后一次状态改变时间 */
	unsigned short sem_nsems; /* 信号量元素个数 */
};

权限结构体如下:

struct ipc_perm
{
	key_t __key;/* 该信号量的键值 key */
	uid_t uid; /* 所有者有效 UID */
	gid_t gid; /* 所有者有效 GID */
	uid_t cuid; /* 创建者有效 UID */
	gid_t cgid; /* 创建者有效 GID */
	unsigned short mode; /* 读写权限 */
	unsigned short __seq; /* 序列号 */
};

使用 IPC_INFO 时,需要提供以下结构体:

struct seminfo
{
	int semmap; /* 当前系统信号量总数 */
	int semmni; /* 系统信号量个数最大值 */
	int semmns; /* 系统所有信号量元素总数最大值 */
	int semmnu; /* 信号量操作撤销结构体个数最大值 */
	int semmsl; /* 单个信号量中的信号量元素个数最大值 */
	int semopm; /* 调用 semop( )时操作的信号量元素个数最大值 */
	int semume; /* 单个进程对信号量执行连续撤销操作次数的最大值 */
	int semusz; /* 撤销操作的结构体的尺寸 */
	int semvmx; /* 信号量元素的值的最大值 */
	int semaem; /* 撤销操作记录个数最大值 */
}

  • 返回值
成功value
GETNCNTsemncnt
GETPIDsempid
GETVALsemval
GETZCNTsemzcnt
IPC_INFO内核中记录所有 SEM 信息的数组的下标最大值
SEM_INFO同 IPC_INFO
SEM_STAT内核中记录所有 SEM 信息的数组,下标为 semid 的信号量的 ID
其他0
失败-1


这里提供代码参考example.c

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值