key_t键和ftok()函数
* 消息队列、信号量和共享内存具有内核持续性(与具体进程周期不相关),故需要在内核用一个全局唯一的Key来标识。
* 这个Key的类型为整数key_t (#include<sys/types.h>),可以在代码写死,也可以用ftok()函数生成- 使用例子:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main()
{
const char *pMsgPath = "/data/home/andyawang/code/ipc/MsgQueue";
key_t key = ftok(pMsgPath, 1);
printf("Key : %d\n", key);
return 0;
}2个命令:ipcs和ipcrm
* ipcs用于显示当前内核这3种IPC的各种信息,ipcrm为删除
* 使用例子:
# ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 0 root 666 12000 6 dest 0x00005fe7 32769 root 666 524288 2 0x00005fe8 65538 root 666 2097152 12 ------ Semaphore Arrays -------- key semid owner perms nsems 0x00008708 32769 root 666 1 0x000086f8 589826 root 666 1 ------ Message Queues -------- key msqid owner perms used-bytes messages 0x5ca04f5b 3473408 root 666 0 0
数据结构 (#include<sys/msg.h>)
struct msqid_ds
{
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue,unused */
struct msg *msg_last; /* last message in queue,unused */
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
unsigned long msg_lqbytes; /* ditto */
unsigned short msg_cbytes; /* current number of bytes on queue */
unsigned short msg_qnum; /* number of messages in queue */
unsigned short msg_qbytes; /* max number of bytes on queue */
__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_ipc_pid_t msg_lrpid; /* last receive pid */
};
* 相关函数
- msgget():创建或打开一个消息队列
- msgsnd()/msgrcv():往消息队列发送/取出消息- msgctl():控制操作,如删除等
* 使用例子:
[MsgQueSvr,cpp]
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
using namespace std;
const int MAXSIZE = 100;
// 消息的数据结构:
// * 最前必须有一个long来作为消息的类型,剩下的可自定义
struct SMsgUnit
{
long type;
int len;
char data[MAXSIZE];
};
int main()
{
struct SMsgUnit sMsg;
key_t iKey;
int iMsgId;
// Get MsgQue Key
const char *pMsgPath = "/data/home/andyawang/code/ipc/MsgQueue";
if ((iKey = ftok(pMsgPath, 1)) == -1) {
cout << "Ftok Err" << endl;
return -1;
}
// 1.msgget
if ((iMsgId = msgget(iKey, IPC_CREAT|IPC_EXCL|0666)) == -1) {
cout << "Msgget Err" << endl;
return -1;
}
// 2.msgrcv & msgsnd
for(int i = 0; i < 5; i ++)
{
msgrcv(iMsgId, &sMsg, sizeof(struct SMsgUnit), 1, 0);
cout << "Svr Recv Msg, type=" << sMsg.type << ", len=" << sMsg.len << ", data=" << sMsg.data << endl;
sMsg.type = 2;
strcpy(sMsg.data, "I Am Svr..");
sMsg.len = strlen(sMsg.data);
msgsnd(iMsgId, &sMsg, sizeof(struct SMsgUnit), 0);
}
// 3.msgctl
if (msgctl(iMsgId, IPC_RMID, NULL) == -1) {
cout << "Msgctl Err" << endl;
return -1;
}
return 0;
}[MsgQueCli.cpp]#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
using namespace std;
const int MAXSIZE = 100;
struct SMsgUnit
{
long type;
int len;
char data[MAXSIZE];
};
int main()
{
struct SMsgUnit sMsg;
key_t iKey;
int iMsgId;
// Get MsgQue Key
const char *pMsgPath = "/data/home/andyawang/code/ipc/MsgQueue";
if ((iKey = ftok(pMsgPath, 1)) == -1) {
cout << "Ftok Err" << endl;
return -1;
}
// 1.msgget
if ((iMsgId = msgget(iKey, IPC_CREAT|0666)) == -1) {
cout << "Msgget Err" << endl;
return -1;
}
// 2.msgsnd
sMsg.type = 1;
strcpy(sMsg.data, "I Am Cli..");
sMsg.len = strlen(sMsg.data);
msgsnd(iMsgId, &sMsg, sizeof(struct SMsgUnit), 0);
// 3.msgrcv
msgrcv(iMsgId, &sMsg, sizeof(struct SMsgUnit), 2, 0);
cout << "Cli Recv Msg, type=" << sMsg.type << ", len=" << sMsg.len << ", data=" << sMsg.data << endl;
return 0;
}
原文:http://blog.csdn.net/yyyiran/article/details/19087407