信号灯
信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制 。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源(临界区,类似于互斥锁),同时,进程也可以修改该标志 。除了用于访问控制外,还可用于进程同步 。
1. 信号灯概述信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制 。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源(临界区,类似于互斥锁),同时,进程也可以修改该标志 。除了用于访问控制外,还可用于进程同步 。信号灯有以下两种类型:
- 二值信号灯:最简单的信号灯形式,信号灯的值只能取0或1,类似于互斥锁 。
注:二值信号灯能够实现互斥锁的功能,但两者的关注内容不同 。信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁 。 - 计算信号灯:信号灯的值可以取任意非负值(当然受内核本身的约束) 。
注意,通常所说的系统V信号灯指的是计数信号灯集 。
3. 信号灯与内核1、系统V信号灯是随内核持续的,只有在内核重起或者显示删除一个信号灯集时,该信号灯集才会真正被删除 。因此系统中记录信号灯的数据结构(struct ipc_ids sem_ids)位于内核中,系统中的所有信号灯都可以在结构sem_ids中找到访问入口 。
2、下图说明了内核与信号灯是怎样建立起联系的:

文章插图
【linux进程间通信——深入理解linux信号量】其中:structipc_ids sem_ids是内核中记录信号灯的全局数据结构;描述一个具体的信号灯及其相关信息 。
其中,struct sem结构如下:
struct sem{int semval; // current valueint sempid; // pid of last operation}从上图可以看出,全局数据结构struct ipc_ids sem_ids可以访问到struct ipc_id ipcid的一个成员:struct kern_ipc_perm;而每个struct kern_ipc_perm能够与具体的信号灯集对应起来是因为在该结构中,有一个key_t类型成员key,而key则唯一确定一个信号灯集struct sem_array;同时,结构struct sem_array的最后一个成员sem_nsems确定了该信号灯在信号灯集中的顺序,这样内核就能够记录每个信号灯的信息了 。kern_ipc_perm结构如下:
//内核中全局数据结构sem_ids能够访问到该结构;struct kern_ipc_perm{key_tkey;//该键值则唯一对应一个信号灯集uid_tuid;gid_tgid;uid_tcuid;gid_tcgid;mode_tmode;unsigned long seq;}/*系统中的每个信号灯集对应一个sem_array 结构 */struct sem_array {struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */time_t sem_otime; /* last semop time */time_t sem_ctime; /* last change time */struct sem *sem_base; /* ptr to first semaphore in array */struct sem_queue *sem_pending; /* pending operations to be processed */struct sem_queue **sem_pending_last; /* last pending operation */struct sem_undo *undo; /* undo requests on this array */unsigned long sem_nsems; /* no. of semaphores in array */};其中,sem_queue结构如下:/* 系统中每个因为信号灯而睡眠的进程,都对应一个sem_queue结构*/struct sem_queue {struct sem_queue * next; /* next entry in the queue */struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */struct task_struct* sleeper; /* this process */struct sem_undo * undo; /* undo structure */int pid; /* process id of requesting process */int status; /* completion status of operation */struct sem_array * sma; /* semaphore array for operations */int id; /* internal sem id */struct sembuf * sops; /* array of pending operations */int nsops; /* number of operations */int alter; /* operation will alter semaphore */};需要C/C++ Linux服务器架构师学习资料私信“资料”(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
文章插图
4. 操作信号灯对信号灯的操作无非有下面三种类型:
1、打开或创建信号灯 与消息队列的创建及打开基本相同,不再详述 。
推荐阅读
- 红茶时间越久越好吗,普洱茶生茶判别
- 神舟十一号飞船的发射时间 神舟十号飞船发射火箭返回时间
- 凤凰山ufo神秘事件 凤凰山UFO事件
- 立冬下雨好还是天晴好?
- 一天最佳三个运动时间是何时?
- 空间站|天舟三号从空间站后端绕前端对接:将迎接天舟四号、神舟十四号载人飞船
- 面试官:知道时间轮算法吗?在Netty和Kafka中如何应用的?
- 灵异真实故事民间 灵异民间故事
- 启元世界:打造AI决策智能体,用小样本实现10的26次方复杂空间决策
- 2021年中国空间站计划 我国空间站将在2022年前后建成并运营
