1.ftok函数
系统建立IPC通讯 (消息队列、信号量和共享内存) 时必须指定一个ID值。通常情况下,该id值通过ftok函数得到
头文件
#include <sys/types.h>
#include <sys/ipc.h>
函数原型:
key_t ftok( const char * fname, int id )
fname就时你指定的文件名(该文件必须是存在而且可以访问的),一般使用当前目录,如:
key_t key;
key = ftok(".", 1); 这样就是将fname设为当前目录。
id是子序号,虽然为int,但是只有8个比特被使用(0-255)。
在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。
当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。
2.键值生成及收发数据代码
(1)读信息代码:
msgGetKey.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf {
long mtype; //消息类型 /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
//int msgget(key_t key, int msgflg);
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);//十六进制
struct msgbuf readBuf;
int msgId = msgget(key,IPC_CREAT|0777);//0777可读可写可执行
if(msgId == -1)//创建消息队列失败
{
printf("get que failuer\n");
}
//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);//读取消息
printf("read form que:%s\n",readBuf.mtext);
struct msgbuf sendBuf = {988,"thank you for reach"};
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//发送消息
return 0;
}
编译:gcc msgGetKey.c -o get
(2)发信息代码:
msgSendKey.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf {
long mtype; //消息类型 /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
//int msgget(key_t key, int msgflg);
struct msgbuf sendBuf = {888,"this is message form quen"};
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);
int msgId = msgget(key,IPC_CREAT|0777);//0777可读可写可执行
if(msgId == -1)//创建消息队列失败
{
printf("get que failuer\n");
}
//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//发送消息
printf("send over\n");
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);//读取消息
printf("readturn form get:%s\n",readBuf.mtext);
return 0;
}
编译:gcc msgSendKey.c -o send
(3)运行流程:
先运行: ./get
后运行: ./send
(4)运行结果:
3.消息队列移除
使用的函数:int msgctl(int msqid, int cmd, struct msqid_ds *buf);
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf {
long mtype; //消息类型 /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
//int msgget(key_t key, int msgflg);
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);//十六进制
struct msgbuf readBuf;
int msgId = msgget(key,IPC_CREAT|0777);//0777可读可写可执行
if(msgId == -1)//创建消息队列失败
{
printf("get que failuer\n");
}
//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);//读取消息
printf("read form que:%s\n",readBuf.mtext);
struct msgbuf sendBuf = {988,"thank you for reach"};
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//发送消息
//int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl(msgId,IPC_RMID,NULL);//IPC_RMID表示消息队列从内核中移除
return 0;
}
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf {
long mtype; //消息类型 /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
//int msgget(key_t key, int msgflg);
struct msgbuf sendBuf = {888,"this is message form quen"};
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);
int msgId = msgget(key,IPC_CREAT|0777);//0777可读可写可执行
if(msgId == -1)//创建消息队列失败
{
printf("get que failuer\n");
}
//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//发送消息
printf("send over\n");
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);//读取消息
printf("readturn form get:%s\n",readBuf.mtext);
msgctl(msgId,IPC_RMID,NULL);//IPC_RMID表示消息队列从内核中移除
return 0;
}
运行结果: