UNIX环境下的消息队列
消息队列和共享内存一样,也是一种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环境下的消息队列的更多相关文章
- MQ在高并发环境下,如果队列满了,如何防止消息丢失?
1.为什么MQ能解决高并发环境下的消息堆积问题? MQ消息如果堆积,消费者不会立马消费所有的消息,不具有实时性,所以可以解决高并发的问题. 性能比较好的消息中间件:Kafka.RabbitMQ,Roc ...
- 【微服务专题之】.Net6下集成消息队列上-RabbitMQ
微信公众号:趣编程ACE关注可了解更多的.NET日常实战开发技巧,如需源码 请公众号后台留言 源码;[如果觉得本公众号对您有帮助,欢迎关注] .Net中RabbitMQ的使用 [微服务专题之].N ...
- Net平台下的消息队列介绍
Net平台下的消息队列介绍 本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架. RabbitMQ:http:// ...
- Unix IPC之Posix消息队列(1)
部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/ar ...
- 消息队列系列(一):.Net平台下的消息队列介绍
本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架. RabbitMQ:http://www.rabbitmq.com ...
- Linux下进程间通信--消息队列
消息队列的定义遍地都是,不想移驾,请看下文: 一.定义: 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认 为是有一个类型,接收者进程接收的数据块可以有不同的类型值.我 ...
- BS架构下使用消息队列的工作流程
异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长. 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有 ...
- UNIX环境下的共享内存
好久没更新博客了,最近几个月一直在忙项目,现在终于有时间进一步学习了.这次记录的是unix环境中共享内存的使用方法. 在我理解,共享内存就是在内存中开辟一段空间,各个毫不相干的进程就可以通过访问这段 ...
- Unix环境下PS1变量的设置
我的ps1命令提示符: export PS1="\[\e[31;1m\]\u @ \[\e[34;1m\]\h \[\e[36;1m\]\w \[\e[33;1m\]\t $ \[\e[37 ...
随机推荐
- 样式单位之px、em、rem
最近在看bootstrap.css的时候看到很多单位都用到rem而不是熟系的px.经学习得知: 1.px精确的单位: 2.em为相对单位(相对父级元素) 3.rem为相对单位(相对根元素 html)
- java的各个队列之间的联系和区别是什么
java的各个并发队列之间的联系和区别 java.util.concurrent是在并发编程中很常用的实用工具类 ArrayBlockingQueue, DelayQueue, LinkedBlock ...
- Css3 常见鼠标滑过效果集合
1.演示地址: http://yaochuxia.github.io/hover/#
- Android OpenGL ES 3.0 纹理应用
本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...
- ^(bitwise exclusive Or).
一个数,进行异或同一个数两次,将得到原来的数,例如: 6 ^ 4 ^ 4 = 6; 0000-0000-0000-0110 ^ 0000-0000-0000-0100 ---------------- ...
- C#.net时间戳转换
//long ticks = (DateTime.Parse(DateTime.Now.ToString(CultureInfo.InvariantCulture)).ToUniversalTime( ...
- [转载]CentOS6.4+Mono3.0.7+Jexus5.2.5
本文章来自互联网,但是本人已经在VM虚拟机里面测试成功,所以分享给大家 1.更新 yum -y update 2.安装Mono源码安装需要的库 yum -y install gcc gcc-c++ a ...
- Java 获取字符串中第N次出现的字符位置
public static int getCharacterPosition(String string){ //这里是获取"/"符号的位置 Matcher slash ...
- oracle 中查看一张表是否有主键,主键在哪个字段上的语句怎么查如要查aa表,
select a.constraint_name, a.column_name from user_cons_columns a, user_constraints b where a.constra ...
- SpringMVC4+thymeleaf3的一个简单实例(篇一:基本环境)
首语:用SpringMVC和thymeleaf实现一个简单的应用,包括基本环境搭建,SpringMVC4和thymeleaf3的整合,页面参数的获取,页面参数验证,以及用MySQL保存数据.我会把步骤 ...