多进程间通信学习之消息队列&共享内存&信号灯集

  • 消息队列:
  • 1、基于内核实现,必须在内核空间创建消息队列;
  • 2、消息队列中的消息由类型和正文组成;
  • 3、消息队列的默认大小为16KB;
  • 运行过程:
  • 1、进程1将消息写入到消息队列,进程2根据消息的类型从消息队列中取得对应的消息;
  • 2、进程1向消息队列中发送消息,可以采用阻塞或者非阻塞的方式;
  • 3、进程2从消息队列中收取消息,也可以采用阻塞或者非阻塞的方式;
  • 常用的接口函数:
  • msgget函数:
  • 功能:创建或者获取一个消息队列;
c 复制代码
	#include <sys/types.h>
	#include <sys/ipc.h>
	#include <sys/msg.h>
	
	int msgget(key_t key, int msgflg);
	/*
		参数:
		    	key:	键值
		
		        	key 	通过ftok获取的
		
		        	IPC_PRIVATE 表示只有亲缘进程间能只用
		
		    	msgflg:消息队列的标志位
		
		        	IPC_CREAT|0666  或者  IPC_CREAT|IPC_EXCL|0666 
		
		返回值:
		
		    	成功 消息队列的id
		
		    	失败 -1 重置错误码
	*/
  • msgsnd函数:
  • 功能:向消息队列中写入一条消息;
c 复制代码
	int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
	/*
		参数:
	
	    	msqid:消息队列的id
	
	    	msgp: 要写入的数据的首地址
	
	    	msgsz:消息正文的大小
	
	    	msgflg:标志位 0 阻塞发送  IPC_NOWAIT 非阻塞发送
	
		返回值:
	    		成功 0
	
	    		失败 -1  重置错误码
	*/
				struct msgbuf {
	
	           		long mtype;       /* 消息的类型 必须大于 0 */
	
	           		char mtext[1];    /* 消息正文 可以自定义 */
	       		};
  • msgrcv函数:
  • 功能:在消息队列中读取一条消息;
c 复制代码
	ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
	/*
		参数:
		
		    	msqid:消息队列的id
		
		    	msgp: 用来保存接收的数据的缓冲区的首地址
		
		    	msgsz:消息正文的大小
		
		    	msgtyp:要接受的消息的类型
		
		        		0 :接收消息队列中第一条消息
		
		        		>0 : 接收指定类型的第一条消息
		
		        		<0 :一般不使用,
		
						表示接收消息队列中第一条类型最小的小于msgtyp的绝对值的消息
		
		            		3-2-5-500-200-8
		
		            		读取时,类型传 -200
		
		            		读取的顺序  2-3-5 
		
		    	msgflg:标志位 0 阻塞接收  IPC_NOWAIT 非阻塞接收
		
		返回值:
		
		    	成功 实际读到的正文的字节数
		
		    	失败 -1  重置错误码
	 */
    	struct msgbuf {

           		long mtype;       /* 消息的类型 必须大于 0 */

           		char mtext[1];    /* 消息正文 可以自定义 */

       	};
  • msgctl函数:
  • 功能:控制消息队列;
c 复制代码
	int msgctl(int msqid, int cmd, struct msqid_ds *buf);
	/*
		参数:
		
		    	msqid:消息队列id
		
		    	cmd:指令
		
		        		IPC_STAT:获取消息队列的属性
		
		        		IPC_SET:设置消息队列的属性
		
		        		IPC_RMID:立即删除消息队列
		
		            			只有消息队列的创建者和所有者以及root用户可以删除消息队列
		
		            			msgctl函数的第三个参数被忽略
		    	buff:
		返回值:
		
		    	成功 	0
		
		    	失败 	-1  	重置错误码
	 */
  • 获取和设置消息队列的属性:
  • 属性结构体:
c 复制代码
	struct msqid_ds {
	
	    	struct ipc_perm msg_perm;     /* IPC权限结构体 */
	
	    	time_t          msg_stime;    /* 最后一次执行msgsnd的时间 */
	
	    	time_t          msg_rtime;    /* 最后一次执行msgrcv的时间 */
	
	    	time_t          msg_ctime;    /* 最后一次被修改的时间 */
	
	    	unsigned long   __msg_cbytes; /* 当前消息队列中的字节数 */
	
	    	msgqnum_t       msg_qnum;     /* 当前消息队列中的消息数 */
	
	    	msglen_t        msg_qbytes;   /* 允许的最大字节数 */
	
	    	pid_t           msg_lspid;    /* 最后一次执行msgsnd的进程的PID */
	
	    	pid_t           msg_lrpid;    /* 最后一次执行msgrcv的进程的PID */
	
	};
	
	struct ipc_perm {
	
	    	key_t          __key;       /* 键值 */
	
	    	uid_t          uid;         /* 所属用户的id */
	
	    	gid_t          gid;         /* 所属用户的组id */
	
	    	uid_t          cuid;        /* 创建者的id */
	
	    	gid_t          cgid;        /* 创建者的组id */
	
	    	unsigned short 	mode;        /* 权限 */
	
	};
  • 共享内存:
  • 1、同样在内核中创建共享内存;
  • 2、进程1和进程2都能够访问到,通过这段内存空间进行数据的传递;
  • 3、共享内存是所有进程间通信方式中,效率最高的,不需要在内核中往返进行拷贝;
  • 4、共享内存的内存空间大小是4KB的整数倍;
  • 信号灯集:
  • 1、实现进程同步的机制;
  • 2、在一个信号灯集中,可以有很多信号灯;
  • 3、这些信号灯集中的信号灯相互独立,每个灯的值的改变都不会影响到其他的信号灯;
  • 4、信号灯的值一般设置为二值量,即0或者1,其中0代表没有资源,1代表有资源;
相关推荐
smilejingwei12 分钟前
TRAE 插件上新 | SQLazy:让 AI 写出可信复杂 SQL
数据库·人工智能·sql
我要见SA姐117 分钟前
GitHub Actions 自动化:5 个真实运维提效案例
运维·数据库·机器学习·oracle·回归
樱花树下的数学喵1 小时前
手写简易 STL string|C++ 字符串底层实现
开发语言·c++
QXWZ_IA2 小时前
边坡监测预算有限时的建设顺序:虚拟基准站与成本账
网络·数据库
极限挑战哥2 小时前
共享电单车联营平台分账架构实践:二清合规与自动分账零人工方案
java·大数据·人工智能·微信小程序·架构·微信公众平台
jimy12 小时前
C++ 报错的 qualifiers 的意思
开发语言·c++
水饺编程2 小时前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
留岁2 小时前
大模型推理部署 · 学习文档
学习
这个DBA有点耶2 小时前
1亿条向量内存降95.4%,延迟降80%:金仓AI原生内核真能解决RAG痛点?
数据库·人工智能·开源
Y3815326622 小时前
用 httpx 写 SerpBase 异步客户端:连接池与超时配置
运维·服务器·数据库