消息队列的结构

读取消息队列中的某个消息,要知道消息队列的msqid和msg_type
ftok函数的使用
key_t ftok( char * fname, int id )
//系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
参数:
fname就时你指定的文件名(该文件必须是存在而且可以访问的)。
id是子序号, 虽然为int,但是只有8个比特被使用(0‐255)。
返回值:
当成功执行的时候,一个key_t值将会被返回,否则 ‐1 被返回
key_t ftok(char * fname, int proj_id);
常见问题:
1.pathname是目录还是文件的具体路径,是否可以随便设置
2.pathname指定的目录或文件的权限是否有要求
3.proj_id是否可以随便设定,有什么限制条件
解答:
1、ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。
2、该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
3、proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;
一个进程向消息队列发送数据块
代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf
{
long mtype;//消息类型
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf sendbuf;
int msgid;
key_t key;
key=ftok("b.c",5);
msgid = msgget(key,0755|IPC_CREAT);
if(msgid == -1)
{
printf("create message queue failed!\n");
return -1;
}
system("ipcs -q");
printf("create message queue success msgid =%d\n",msgid);
//init msgbug
sendbuf.mtype = 100;
while(1)
{
memset(sendbuf.mtest,0,128);//清空数据
printf("please input to massage queue:\n");
fgets(sendbuf.mtest,128,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
}
return 0;
}
通过ftok函数获得一个消息队列关联值key,然后根据key来创建(存在就打开)一个消息队列,并取得它的msqid给msgid变量里,创一个数据块,且结构体里必须包含long mtype;//消息类型,因为后面从消息队列中读取消息要根据msqid和mtype来找到要读取的消息。
另一个进程读取消息队列的数据块
代码:
msg_write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf
{
long mtype;
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf readbuf;
int msgid;
int readret;
key_t key;
key=ftok("b.c",5);
msgid = msgget(key,0755|IPC_CREAT);
if(msgid == -1)
{
printf("create message queue failed!\n");
return -1;
}
system("ipcs -q");
printf("create message queue success msgid =%d\n",msgid);
//init msgbug
readbuf.mtype = 99;
while(1)
{
memset(readbuf.mtest,0,128);//清空数据
readret=msgrcv(msgid,(void *)&readbuf,128,100,0);
printf("message is: %s\n",readbuf.mtest);
printf("total have %d byte\n",readret);
}
return 0;
根据msgid和my要读取刚刚msg_write.c里把发送给消息队列的消息。
执行结果:
一些注意的细节:
key_t ftok( char * fname, int id ),因为key是根据第一个参数:fname文件里的信息和第二个参数id结合产生的,所以fname文件如果删除重新创建,那么它的文件信息就会发送改变,则key值也会发生改变。