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

  • 消息队列:
  • 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代表有资源
相关推荐
2401_832131951 分钟前
Python单元测试(unittest)实战指南
jvm·数据库·python
猷咪26 分钟前
C++基础
开发语言·c++
IT·小灰灰27 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧29 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q30 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳030 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾30 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683634 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
打工的小王39 分钟前
redis(四)搭建哨兵模式:一主二从三哨兵
数据库·redis·缓存
飞机和胖和黄1 小时前
考研之王道C语言第三周
c语言·数据结构·考研