首页 / LINUX / linux消息队列应用编程
linux消息队列应用编程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了linux消息队列应用编程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4680字,纯文字阅读大概需要7分钟。
内容图文
消息队列:
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法
每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值
消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)
对比管道和消息:
管道:流管道 消息:有边界
先进先出 可以后进入、先出来
消息大小三大限制
cat /proc/sys/kernel/msgmax最大消息长度限制
cat /proc/sys/kernel/msgmnb消息队列总的字节数
cat /proc/sys/kernel/msgmni消息条目数
IPC对象数据结构
内核为每个IPC对象维护一个数据结构
struct ipc_perm {
key_t __key; /* Key supplied to xxxget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
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) */
};
消息队列在内核中的表:
消息队列函数:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
intmsgget(key_t key, intmsgflg);
intmsgctl(intmsqid, intcmd, structmsqid_ds *buf);
intmsgsnd(intmsqid, const void *msgp, size_tmsgsz, intmsgflg);
ssize_tmsgrcv(intmsqid, void *msgp, size_tmsgsz, long msgtyp, intmsgflg);
msgget函数
功能:用来创建和访问一个消息队列
原型:intmsgget(key_t key, intmsgflg);
参数:
key: 某个消息队列的名字
msgflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该消息队列的标识码;失败返回-1
msgget函数参数关系图:
msgctl函数
功能:消息队列的控制函数
原型:intmsgctl(intmsqid, intcmd, structmsqid_ds *buf);
参数:
msqid: 由msgget函数返回的消息队列标识码
cmd:是将要采取的动作,(有三个可取值)
返回值:成功返回0,失败返回-1
cmd:将要采取的动作(有三个可取值),分别如下:
消息队列的发送和接受:
msgsnd函数
功能:把一条消息添加到消息队列中
原型:intmsgsnd(intmsqid, const void *msgp, size_tmsgsz, intmsgflg);
参数:
msgid: 由msgget函数返回的消息队列标识码
msgp:是一个指针,指针指向准备发送的消息,
msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情
返回值:成功返回0;失败返回-1
msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误。
消息结构在两方面受到制约。首先,它必须小于系统规定的上限值;其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
消息结构参考形式如下:
structmsgbuf {
long mtype;
char mtext[100];
}
msgrcv函数
功能:是从一个消息队列接收消息
原型:ssize_tmsgrcv(intmsqid, void *msgp, size_tmsgsz, long msgtyp, intmsgflg);
参数:
msgid: 由msgget函数返回的消息队列标识码
msgp:是一个指针,指针指向准备接收的消息,
msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgtype:它可以实现接收优先级的简单形式
msgflg:控制着队列中没有相应类型的消息可供接收时将要发生的事
返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1
msgtype=0返回队列第一条信息
msgtype>0返回队列第一条类型等于msgtype的消息
msgtype<0返回队列第一条类型小于等于msgtype绝对值的消息,并且是满足条件的消息类型最小的消息
msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误。
msgflg=MSG_NOERROR,消息大小超过msgsz时被截断
msgtype>0且msgflg=MSG_EXCEPT,接收类型不等于msgtype的第一条消息。
消息队列综合api使用:
同一个进程,使用消息队列代码示例:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include <sys/types.h> 4 #include <sys/ipc.h> 5 #include <sys/msg.h> 6 #include<errno.h> 7 #include<string.h> 8 #include <sys/types.h> 9 #include <unistd.h> 10struct msg_buf 11{ 12long mtype; 13char data[255]; 14}; 1516/* 注意long 和int在32bit 和 64bit系统之下是不一样的 17structmsg_buf 18{ 19 long mtype; 20 char data[255]; 21}; 22*/2324int main() 25{ 26 key_t key; 27int msgid; 28int ret; 29struct msg_buf msgbuf; 30int msgtype = getpid(); 31//系统建立IPC通讯 (消息队列、信号量和共享内存) 时必须指定一个ID值。通常情况下,该id值通过ftok函数得到。32 key=ftok("./msgfile",‘a‘); 33 printf("key =[%x]\n",key); 3435 printf("sizeof(long):%ld, sizeof(int):%d \n", sizeof(long), sizeof(int)); 36//用来创建和访问一个消息队列37 msgid=msgget(key, IPC_CREAT |IPC_EXCL|0666); //通过文件对应3839if(msgid==-1) 40 { 41if (errno == EEXIST) 42 { 43 printf("EEXIST:.....\n"); 44 key=ftok("./msgfile",‘a‘); 45 msgid=msgget(key, IPC_CREAT|0666); //通过文件对应46 } 47else48 { 49 printf("create error\n"); 50 perror("msget: \n"); 51return -1; 52 } 5354 } 55 printf("msgid:%d \n", msgid); 5657 msgbuf.mtype = msgtype; // getpid();5859 printf("getpid(): %d \n", getpid()); 60 strcpy(msgbuf.data,"hello world!"); 61//把一条data消息添加到消息队列,IPC_NOWAIT表示队列满不等待,返回EAGAIN错误62 ret = msgsnd(msgid,&msgbuf, sizeof(msgbuf.data), IPC_NOWAIT); 63if(ret==-1) 64 { 65 printf("send message err\n"); 66 perror("senderr"); 67return -1; 68 } 69 sleep(1); 7071 memset(&msgbuf,0,sizeof(msgbuf)); 72//是从一个消息队列接收消息,队列没有可读消息不等待,返回ENOMSG错误73 ret=msgrcv(msgid, &msgbuf, sizeof(msgbuf.data), msgtype, IPC_NOWAIT); 74if(ret==-1) 75 { 76 printf("recv message err\n"); 77 perror("dd"); 78return -1; 79 } 80 printf("recvmsg =[%s]\n",msgbuf.data); 81return0; 82 }
编译执行程序,结果如下所示:
消息队列项目开发案例(消息队列实现回射客户/服务器)示意:
原文:http://www.cnblogs.com/liunianshiwei/p/6112024.html
内容总结
以上是互联网集市为您收集整理的linux消息队列应用编程全部内容,希望文章能够帮你解决linux消息队列应用编程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。