消息队列和共享内存一样,也是一种IPC对象。消息队列其实就是消息的链表,每一则消息都是用户自己的结构体。服务端这边创建消息队列,客户端这边打开消息队列,两个进程就可以进行通信。创建和打开消息队列使用函数msgget,发送消息到消息队列使用函数msgsnd,从消息队列中取出消息使用函数msgrcv,通信完毕后删除消息队列使用函数msgctl。这四个函数就是消息队列通信编程主要用到的函数,man命令就可以看到他们的详细信息。

  前面说到消息是用户自己构造的结构体,其实这个结构体也是有讲究的,这是linux给出的原型

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

  第一个是整形数字,标识消息的类型,可由用户自己定义。第二个就是消息的内容。其他部分可由用户自己添加。下面直接贴代码吧,感觉代码比文字更直观。我这里只是扫盲式的学了一下,接收消息的时候比较简单粗暴,直接接受了当前队列的第一则消息,没有设置其他的标志。

/*send.c*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>


struct msgt
{
/*消息类型*/
int msgtype;
char student_num[20];
char name[20];
};


int main(int argc, char const *argv[])
{
int msgid;
int running = 1;
int msg_type;
char number[20];
char str[20];


struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt));


/*构造键值*/
key_t key = ftok(".", 4);


/*创建消息队列*/
msgid = msgget(key, IPC_CREAT|0666);
printf("msgid is %d\n", msgid);


/*循环*/
while(running)
{
printf("please input message type, 0 for quit\n");
/*从键盘中读入消息类型和数据*/
scanf("%d", &msg_type);
if(msg_type == 0)
{
running = 0;
msgs->msgtype = msg_type;
msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0);
break;
}
printf("please input your student number\n");
scanf("%s", &number);


printf("please input your name\n");
scanf("%s", str);
/*将消息发送到消息队列*/
msgs->msgtype = msg_type;
strcpy(msgs->student_num, number);
strcpy(msgs->name, str);
msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0);


}


/*删除消息队列*/
msgctl(msgid, IPC_RMID, 0);


free((void *) msgs);


return 0;
}

 
/*recieve.c*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>


struct msgt
{
/*消息类型*/
int msgtype;
char student_num[20];
char name[20];
};


int main(int argc, char const *argv[])
{

int i;
int size;
int msgid;

struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt));


/*构造键值*/
key_t key = ftok(".", 4);


/*打开消息队列*/
msgid = msgget(key, IPC_EXCL);


printf("msgid is %d\n", msgid);


while(1)
{
size = msgrcv(msgid, msgs, sizeof(struct msgt), 0, 0);
if(size == -1)
return;
printf("your student number is %s\nyour name is %s\nsize is %d\n", msgs->student_num, msgs->name, size);

}
free((void *) msgs);


return 0;
}

 

  这里说点写这个程序出现的问题,一开始定义消息结构体的时候我是这么干的

struct msgt* msgs;

  正常运行发送和接收都还好,但是当send输入0退出程序时就出现段错误了,最后用core dump定位才发现定义结构体指针没有初始化,就这破问题调了好久,血淋淋的教训。以后再敲代码的时候一定要记住,结构体指针需要malloc初始化!!!嗯!

  如果有错误或者疑问,欢迎指出!

UNIX环境下的消息队列的更多相关文章

  1. MQ在高并发环境下,如果队列满了,如何防止消息丢失?

    1.为什么MQ能解决高并发环境下的消息堆积问题? MQ消息如果堆积,消费者不会立马消费所有的消息,不具有实时性,所以可以解决高并发的问题. 性能比较好的消息中间件:Kafka.RabbitMQ,Roc ...

  2. 【微服务专题之】.Net6下集成消息队列上-RabbitMQ

    ​ 微信公众号:趣编程ACE关注可了解更多的.NET日常实战开发技巧,如需源码 请公众号后台留言 源码;[如果觉得本公众号对您有帮助,欢迎关注] .Net中RabbitMQ的使用 [微服务专题之].N ...

  3. Net平台下的消息队列介绍

    Net平台下的消息队列介绍   本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架.       RabbitMQ:http:// ...

  4. Unix IPC之Posix消息队列(1)

    部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/ar ...

  5. 消息队列系列(一):.Net平台下的消息队列介绍

    本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架.       RabbitMQ:http://www.rabbitmq.com ...

  6. Linux下进程间通信--消息队列

    消息队列的定义遍地都是,不想移驾,请看下文: 一.定义: 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认 为是有一个类型,接收者进程接收的数据块可以有不同的类型值.我 ...

  7. BS架构下使用消息队列的工作流程

    异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长. 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有 ...

  8. UNIX环境下的共享内存

    好久没更新博客了,最近几个月一直在忙项目,现在终于有时间进一步学习了.这次记录的是unix环境中共享内存的使用方法.  在我理解,共享内存就是在内存中开辟一段空间,各个毫不相干的进程就可以通过访问这段 ...

  9. Unix环境下PS1变量的设置

    我的ps1命令提示符: export PS1="\[\e[31;1m\]\u @ \[\e[34;1m\]\h \[\e[36;1m\]\w \[\e[33;1m\]\t $ \[\e[37 ...

随机推荐

  1. SQL Server 的远程连接(转载)

    SQL Server默认是不允许远程连接的,如果想要在本地用SSMS连接远程服务器上的SQLServer2012数据库,需要确认以下环节: 1)如果是工作组环境,则需要使用SQL Server身份验证 ...

  2. Initializer block.

    Ref: Initializing Fields Instance initializers are permitted to refer to the current object via the ...

  3. struts2中方法拦截器(Interceptor)的中的excludeMethods与includeMethods的理解

    http://www.cnblogs.com/langtianya/archive/2013/04/10/3012205.html

  4. oracle还原数据库及遇到的问题

    1. 第一:用安装数据库时的管理员用户登录:创建一个新的用户,如: //创建用户123密码456 create user 123 identified by 456;第二:授权,赋予dba的权限 gr ...

  5. 【转】iOS-Core-Animation-Advanced-Techniques(五)

    原文:http://www.cocoachina.com/ios/20150105/10829.html 图层时间和缓冲 图层时间 时间和空间最大的区别在于,时间不能被复用 -- 弗斯特梅里克 在上面 ...

  6. 文字排版--下划线(text-decoration:underline)

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  7. 文字排版--字体(font-family)

    我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性.下面我们来看一个例子,下面代码实现:为网页中的文字设置字体为宋体. body{font-family:"宋体"; ...

  8. HTML页面中启用360浏览器极速模式

    今天做页面突然遇到浏览器一直在兼容模式下运行,体验不好,通过查询文档,在<head>中加入<meta name="renderer" content=" ...

  9. python模块之hashlib加密

    40.加密模块:hashlib      1.           >>> import hashlib >>> ret1 = hashlib.md5()     ...

  10. 常用Firefox扩展

    最近思维混乱,无心做事,故整理下东西.(PS:有些是firefox自带的.) 1.标签页管理器 2.1.41 用途:在新标签页打开书签.历史.地址.搜索. 主页:http://www.firefox. ...