Linux POSIX Message Queue 使用体会
来源:互联网 发布:软件白名单 编辑:程序博客网 时间:2024/06/06 03:06
最近正在Linux上使用POSIX Message Queue(以下简称MQ)在进程间通讯,对目前我这系统发行版和编译器来讲,MQ用起来有一点体会,是教程是没有说明的,或者我看的不够仔细,没有发现
参考资料
《The Linux Programming Interface - A Linux and UNIX System Programming Handbook》2010
测试系统:
Linux Mint 3.11.0-12-generic x86_64 GNU/Linux, MPICH2, mpic++ (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
先上代码
// UNIX IPC functionalities#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <string.h>// POSIX Message Queue#include <mqueue.h>// C++ header files#include <iostream>#include <sstream>#include <string>int receiveMsg(mqd_t *mqdes){unsigned int prio; // priority of the messagestruct mq_attr attr; // attributessize_t numRead; // size of messageif (mqdes == NULL){std::cout << "mqdes == NULL" << std::endl;exit(EXIT_FAILURE);}do{sleep(1);std::cout << "Check for new message." << std::endl;if (mq_getattr(*mqdes, &attr) == -1){// this is an errorstd::cout << "In receiveMsg(), get attribute error." << std::endl;exit(EXIT_FAILURE);}}while (attr.mq_curmsgs == 0);// allocate memory for the incoming messageschar * buffer = (char *)malloc(attr.mq_msgsize);if (buffer == NULL){std::cout << "In receiveMsg(), malloc error." << std::endl;exit(EXIT_FAILURE);}memset(buffer,0,attr.mq_msgsize);// test use//memset(buffer,1,attr.mq_msgsize);for (int i=0;i<attr.mq_curmsgs;++i){numRead = mq_receive(*mqdes, buffer, attr.mq_msgsize, &prio);if (numRead == -1){std::cout << "In receiveMsg(), mq_receive() error." << std::endl;exit(EXIT_FAILURE);}// print the message to the standard outputstd::cout << "In receiveMsg(), buffer = " << buffer << ", with strlen(buffer) = " << strlen(buffer) << std::endl;std::cout << "buffer = ";for (int j=0;j<strlen(buffer);++j){std::cout << (unsigned int)(buffer[j]) << " ";}std::cout << std::endl;}free(buffer);return 0;}int main(int argc, char *argv[]){// create the POSIX message queuemqd_t mqdes; // descriptormqdes = mq_open("/mymq", O_CREAT | O_RDWR | O_NONBLOCK, 0666, NULL);if (mqdes == (mqd_t) -1){std::cout << "Open MQ failed!" << std::endl;exit(EXIT_FAILURE);}// begin to receive messageif (receiveMsg(&mqdes) != 0){std::cout << "receiveMsg() returns error code." << std::endl;}mq_close(mqdes);mq_unlink("/mymq");exit(EXIT_SUCCESS);}
话不多说啦,体会:
=========== 体会开始 ==============
Message其实是byte计数的内存数据,不是字符串!
=========== 体会结束 ==============
Message这名字起的挺广泛,而且看手册,举的例子也是传输的字符串。于是在自己实现时,就想当然的认为MQ其实时传输的是字符串,但这是不对的。
今天实际调试时就出现了这个问题,具体表现形式是mq_receive()函数调用以后,buffer里正常字符串结尾有好多奇怪的字符。刚开始还感觉是不是字符编码的问题,在OS上查了一圈,感觉又不像,最后发现问题出在没有对buffer进行初始化。
使用没有初始化的内存是禁忌的,但是当时调试时偷懒了,因为下意识地认为,发送的Message是字符串,言下之意是一定有一个结尾'\0'字符自动添加到buffer里。其实不是这样的,在《手册》的实例中,也明确表达了,发送的Message的长度是一个字符串的strlen()结果,就是说,不包括最后一个'\0'。虽然发送时以一个字符串的头地址作为待发送内容的起始,但是最终发送的长度仅是strlen(),比实际的字符串占用内存少了一个byte。在mq_receive()时,MQ也不会自动添加最后一个'\0',因为没这个必要 ---- Message压根就不是字符串。
所以回顾mq_receive()函数的声明,恍然大悟
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
现在理解了,MQ的Message事实上是一段用byte计数的内存,MQ将这块内存以消息的形式发送给kernel,其他进程再从kernel中获取(复制)这块内存中的数据。
事实上,要是就想发送字符串,有两种方法,要么发送时多发一个字节,要么接收之前将buffer初始化,并且一定要初始化为0,否则就会出现我今天早些时候遇到的问题,尾巴上一大堆诡异的字符(可以通过receiveMsg()中的memset()调试这个bug)。
P.S.: 发送Message用的是python2.7代码,从这里获取,安装之前需要安装python2.7-dev。
https://pypi.python.org/pypi/posix_ipc
- Linux POSIX Message Queue 使用体会
- POSIX message queue
- 消息队列 posix message queue
- Posix message queue 消息队列
- semaphore & ipc_message posix message queue & ipc_shared Memory
- Linux IPC - Message Queue
- linux message queue msgget
- Linux Posix Timer使用
- Linux程序设计笔记--IPC操作--message queue
- Linux IPC System V Message Queue
- linux下消息队列(Message queue)
- Message Queue
- message queue
- Message Queue
- Message queue
- unix/linux 进程通讯(posix queue )示例
- 使用linux的体会
- 消息队列(Message Queue)简介及其使用
- Eclipse ModernGoon
- 再谈 Linux下的nanosleep函数
- “System.Web.HttpRequestBase”未被引用的程序
- 1006-HBase操作实战(JAVA API模式)
- GuozhongCrawler系列教程 (4) StartContext详解
- Linux POSIX Message Queue 使用体会
- 策略模式--商场收费系统
- android studio添加三方类库(module)
- linux常用命令
- vs2013中QT信号槽绑定
- difference-in-differences with fixed effects
- 最长公共子序列
- hdu 2115 I Love This Game
- C++对C的函数拓展 - 默认参数