消息队列的知识忘得差不多了,然后今天重新复习一下 参考的是linux高级程序设计第三版
将书上的代码编译(ch11下的两个文件 msg_receiver_example.c.c和msg_sender_example.c.c)
结果竟然收不到信息, 书上说可以实现两个应用之间互相收发信息 大概的代码如下(为了简化 我将其整合 在一个应用中收发)
#include<stdio.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/msg.h> #include<string.h> #define BUF_SIZE (1024) struct msgbuf{ int type; char data[BUF_SIZE]; }; int main(int argc,char *argv[]) { key_t key=ftok(".",100); int msgid=msgget(key,IPC_CREAT|0600); if(fork()==0)//send { while(1) { printf("pls input msg to send:"); char buf[128]; fgets(buf,128,stdin); struct msgbuf sendbuf; memset(&sendbuf,0,sizeof(struct msgbuf)); sendbuf.type=2; //send msg type=2 strcpy(sendbuf.data,buf); msgsnd(msgid,&sendbuf,strlen(buf),0); } } else//recv { while(1) { struct msgbuf mybuf; memset(&mybuf,‘\0‘,sizeof(mybuf)); msgrcv(msgid,&mybuf,BUF_SIZE,2,0); //recv msg type=2 printf("\nrecv msg type:%d, %s",mybuf.type,mybuf.data); } } }
程序很简单,创建消息队列后 父进程读取终端输入并写入消息队列,子进程则读消息队列 消息类型都是2
找了很久一直没发现问题, 首先怀疑消息类型的值有问题 文档说type=0则读取任意类型 否则读取类型为type的消息
因此试着将子进程中的2改成0,然后编译 竟然成功了, 但为何设置其他值就不成功呢?
这个问题折腾大半天,最终发现是type类型有问题 linux下man文档中是long,而这边是int
照道理说 long不是和int一样都是4个字节吗,然后我将其字节长度打印了一下竟然是:
int:4,long:8
OMG... 原来long在32位系统下是4字节,在64位下则是8字节,习惯用32位系统都没关注过这个问题
考虑到程序可移植性 就不能任性的将type随便改成int了
改成long之后在32位和64位系统下测试均通过
至于为什么类型为int的时候 0也能收到 没有继续深究 猜测是字节错位了 判断类型的时候凑出来的类型刚好为
原文:https://www.cnblogs.com/MWDEYI/p/14888416.html