热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

systemV消息队列(msg)

头文件:sysmsg.h查看:ipcs命令结构体:自定义消息缓冲区结构msgbuf:mtype:消息类型(必须是long型;必须是结构
头文件:

sys/msg.h


查看:

ipcs命令


结构体:

自定义消息缓冲区结构msgbuf:

mtype:

消息类型(必须是long型;必须是结构体第一个变量)。

mtext:

消息数据(可以随意定义)。

例子:

struct msgbuf{  
    long mtype;/* must > 0 */  
    char mtext;/* data */
};


创建消息队列/消息队列ID获取:

int msgget(key_t  key,int  msgflg);

key:

IPC键(两种获取方式)。

1.key_t  ftok(char* path,int id);

(path,id随意指定。path不存在则返回的key是-1)

2.IPC_PRIVATE

(通常用于亲缘进程)。

msgflg:

IPC_CREAT创建

IPC_CREAT|TPC_EXCL

权限:

	用户读	用户写	组读	        组写	        其他读	        其他写
宏	MSG_R	MSG_W	MSG_R>>3	MSG_W>>3	MSG_R>>6	MSG_W>>6
数值	0400	0200	0040	0020	0004	0002

可以使用八进制数字

例如:
0666

0表示八进制数字
第一个6表示创建者权限为读写(6=4+2)
第二个6表示同组权限为读写(6=4+2)
第三个6表示其他权限为读写(6=4+2)

返回值:

-1—————失败

非负整数——消息队列标识

代码:

IPC键为IPC_PRIVATE:

#include 
#include 
#include 
#include 
#include 
struct msgbuf {
       long mtype;       /* message type, must be > 0 */
       char mtext[1];    /* message data */
   };

int main(){
	int id = msgget(IPC_PRIVATE,O_CREAT|O_RDWR|0644);
	if(-1 == id){
		perror("msgget error");
		return 1;
	}
	char str[] = "this is msg";
	struct msgbuf* buf = malloc(sizeof(str)+sizeof(long));
	buf->mtype= 7;
	strcpy(buf->mtext,str);
	if(!fork()){
		sleep(3);
		msgsnd(id,buf,sizeof(str),0);
	}else{
//		sleep(1);
		bzero(buf,sizeof(str)+sizeof(long));
		msgrcv(id,buf,sizeof(str),-11,0);
		printf("mtype:%d\nrecv :%s\n",buf->mtype,buf->mtext);
	}
	msgctl(id,IPC_RMID,NULL);
}


IPC键为key:

#include 
#include 
#include 

int main(int argc,char* argv[]){
	key_t key = ftok(argv[1],1);//argv【1】为已存在的一个路径。通过相同路径生成的key进行通信。
	if(-1 == key){
		perror("ftok error");
		return 1;
	}
	int id = msgget(ftok(argv[1],1),IPC_CREAT|O_RDWR|0644);
	if(-1 == id){
		perror("msgget error");
		return 1;
	}
	printf("msqid:%d\n",id);
}



发送消息:

int msgsnd(int msgid,const void* msgbuf,size_t  msgsz,int  msgflg);

msgid:

消息队列标识。

msgbuf:

消息队列结构体(以一个长整型成员变量开始的结构体)。

msgsz:

消息长度。(不包括长整型变量)。

msgflg:

控制函数行为:

0—————————忽略。

IPC_NOWAIT————如果消息队列为空,则返回一个ENOMSG,并将控制权交回调用函数的进程。

MSG_NOERROR——如果函数获取的消息长度大于msgsz,将只返回msgsz长度的信息,剩下的部分被丢弃了。

MSG_EXCEPT———当msgtyp≥0时,接收类型不等于msgtype的第一条消息。

返回值:

0——成功

-1——失败

代码:

(注意,要用root用户再能发送,否则权限不够;路径是真实存在的)

#include 
#include 
#include 
#include 
#include 
#include 
struct msgbuf{
	long mtype;
	char mtext[1];
};
int main(int argc,char* argv[]){
	int c,flag = 0;
	while((c = getopt(argc,argv,"n")) !=-1){
		switch(c){
		case 'n':
			flag=IPC_NOWAIT;
			break;
		}
	}
	if(optind != argc - 3){
		printf("usage:%s [-n]   \n",argv[0]);
		return 1;
	}

	int id = msgget(ftok(argv[optind],1),O_WRONLY);
	if(-1 == id){
		perror("msgget error");
		return 1;
	}
	size_t msglen = strlen(argv[optind+1])+1;
	struct msgbuf* buf = malloc(sizeof(long)+msglen);
	buf->mtype = atoi(argv[optind+2]);
	strcpy(buf->mtext,argv[optind+1]);
	
	if(-1 == msgsnd(id,buf,msglen,flag)){
		perror("fcntl error");
		return 1;
	}



接收消息:

int msgrcv(int msgid,void* msgbuf,size_t msgsz,long int msgtype,int msgflg);

msgid:

消息队列标识。

msgbuf:

消息结构体。

msgsz:

消息长度(不包括长整型变量)。

msgtype:

接收优先级。

0————获取队列中优先级数最小的消息。

大于0——获取具有相同消息类型的第一个信息。

小于0——获取类型等于或小于msgtype的绝对值的消息(优先级数从小到大输出)。

msgflg:

控制函数行为(同发送消息中的msgflg)。

返回值:

非负整数——接收到的消息长度。

-1—————失败。

代码:

(要用root用户接受,头则权限不够;路径必须与发送路径一致)

#include 
#include 
#include 
#include 
#include 
#include 
struct msgbuf{
	long mtype;
	char mtext[1];
};
int main(int argc,char* argv[]){
	int c,flag = 0;
	while((c = getopt(argc,argv,"n")) !=-1){
		switch(c){
		case 'n':
			flag=IPC_NOWAIT;
			break;
		}
	}
	if(optind != argc - 2){
		printf("usage:%s [-n]  \n",argv[0]);
		return 1;
	}

	int id = msgget(ftok(argv[optind],1),O_RDONLY);

	if(-1 == id){
		perror("msgget error");
		return 1;
	}
	size_t msglen = BUFSIZ;
	struct msgbuf* buf = malloc(sizeof(long)+msglen);
	
	if(-1 == msgrcv(id,buf,msglen,atoi(argv[optind+1]),flag)){
//	if(-1 == msgrcv(id,buf,msglen,-10,flag)){
		perror("fcntl error");
		return 1;
	}
	printf("read:%s",buf->mtext);
}



消息控制:

int msgctl(int msgid,int cmd,struct msqid_ds* buf);

msgid:

消息队列标识。

cmd:

IPC_STAT——获取当前消息队列控制信息。

IPC_SET——设置当前消息队列控制信息。

IPC_RMID——删除消息队列。

buf:

消息队列模式结构:

msg_perm.mode——消息队列读写模式。

msg_qbytes————队列最大大小。

msg_cbytes————当前队列大小。

msg_qnum————当前队列消息数。

结构体:

struct msqid_ds {
               struct ipc_perm msg_perm;     /* Ownership and permissions */
               time_t          msg_stime;    /* Time of last msgsnd(2) */
               time_t          msg_rtime;    /* Time of last msgrcv(2) */
               time_t          msg_ctime;    /* Time of last change */
               unsigned long   __msg_cbytes; /* Current number of bytes in
                                                queue (nonstandard) */
               msgqnum_t       msg_qnum;     /* Current number of messages
                                                in queue */
               msglen_t        msg_qbytes;   /* Maximum number of bytes
                                                allowed in queue */
               pid_t           msg_lspid;    /* PID of last msgsnd(2) */
               pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
           };

返回值:

0——成功

-1——失败

例子:

删除消息队列:

msgctl(msqid,IPC_RMID,NULL);

代码:

#include 
#include 

int main(int argc,char* argv[]){
	int i;
	for(i=1;i


获得当前消息队列信息代码:

#include 
#include 
#include 
#include 
#include 

int main(int argc,char* argv[]){
	key_t key = ftok(argv[1],1);
	if(-1 == key){
		perror("ftok error");
		return 1;
	}
	int id = msgget(ftok(argv[1],1),O_RDWR);
	if(-1 == id){
		perror("msgget error");
		return 1;
	}
	struct msqid_ds ds; 
	msgctl(id,IPC_STAT,&ds);
	printf("msg_qnum:%ld msg_qsize:%ld msg_cbyte:%ld\n",ds.msg_qnum,ds.msg_qbytes,ds.__msg_cbytes);
}





推荐阅读
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
author-avatar
归向大海_651
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有