- 往消息队列中发送消息,消息的类型如结构体Msg所示:
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
typedef struct
{
long type;
char name[20];
int age;
}Msg;
int main(int argc, char const *argv[])
{
key_t key = ftok("/home/test/msgq",'8');
int msgid = msgget(key, IPC_CREAT|O_WRONLY|0777);
printf("send-key:%x , msgid:%d\n",key,msgid);
if (msgid < 0)
{
perror("msgget error!");
exit(-1);
}
Msg m;
while(1){
memset(&m,0,sizeof(m));
puts("please input your type name age:");
scanf("%ld%s%d",&m.type, m.name,&m.age);
msgsnd(msgid, &m,sizeof(m) - sizeof(m.type),0);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
- 从消息队列中读取数据
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
typedef struct{
long type;
char name[20];
int age;
}Msg;
int main(int argc, char const *argv[])
{
//该路径可以随便设置,但是发送接收两端保持一致即可
//该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
//proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255
key_t key = ftok("/home/test/msgq",'8');
int msgid = msgget(key,O_RDONLY);
printf("read-key:%x , msgid:%d\n",key,msgid);
if(msgid<0)
{
perror("msgget error!");
exit(-1);
}
Msg rcv;
long type;
ssize_t result = 0;
while(1){
memset(&rcv, 0, sizeof(rcv));
puts("please input type you want!");
scanf("%ld",&type);
result = msgrcv(msgid,&rcv, sizeof(rcv) - sizeof(type), type, IPC_NOWAIT);
printf("result=:%d\n", result );
//读取不到,立马返回,返回-1,不会一直阻塞.
//如果把 IPC_NOWAIT改成0,msgrcv会一直阻塞,知道队列中有该条消息才往下执行
if (result == -1)
{
printf("there is no msg what you want, pls check again\n");
continue;
}
printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
A: 如下截图往消息队列中发送了3条消息
B: 然后从消息队列中可以根据消息类型读取(可以指定消息类型读取,没有顺序,每条消息只能读取一次,重复读取或者读取不存在的消息msgrcv(最后一个参数设定为IPC_NOWAIT)将会返回-1)
C: 通过ipcs 查看消息队列,其中key和msgid跟代码打印的log保持一致.
D: 如果此时此时 ipcrm -q 1048576 或者 ipcrm -Q 0xffffffff ,则内核队列会删除,此时再次运行对应的程序,由于两者之间建立的消息通道已经被删除,所以无法再次建立通信了
E: 经测试发现ftok第一个参数: 该文件路径/home/test/msgq 不一定真实存在,但是发送端和接收端必须保持一致.