C语言 NOTE33

系统编程之信号量



在这里插入图片描述

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
GETNCNT semncnt
GETPID sempid
GETVAL semval
GETZCNT semzcnt
IPC_INFO 内核中记录所有 SEM 信息的数组的下标最大值
SEM_INFO 同 IPC_INFO
SEM_STAT 内核中记录所有 SEM 信息的数组,下标为 semid 的信号量的 ID
其他 0
失败 -1


这里提供代码参考example.c

发布了52 篇原创文章 · 获赞 2 · 访问量 1993

猜你喜欢

转载自blog.csdn.net/weixin_42191545/article/details/104192153
今日推荐