IPC之消息队列
来源:互联网 发布:udp监听端口 编辑:程序博客网 时间:2024/05/16 07:26
key_t键和ftok()函数
* 消息队列、信号量和共享内存具有内核持续性(与具体进程周期不相关),故需要在内核用一个全局唯一的Key来标识。
* 这个Key的类型为整数key_t (#include<sys/types.h>),可以在代码写死,也可以用ftok()函数生成* key_t ftok( const char * fname, int id )
- fname为已存在的文件(不存在返回-1),id为子序号。通过fname文件索引节点号加上子序号构造Key
- 使用例子:
#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
* 内核维护的一个以消息为单位的队列,实质为一个链表结构
数据结构msqid_ds (#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 */};
* 相关函数
#include <sys/ipc.h>#include <sys/msg.h>// 创建或打开一个消息队列int msgget(key_t key, int msgflg);// 往消息队列发送消息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);// 控制操作,如删除等int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
* 使用例子:
[服务端:MsgQueSvr,cpp,循环 { 接收消息类型为1的消息之后,就发送消息类型为2的消息 } ]
#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,发送消息类型为1的消息之后,就接收消息类型为2的消息 ]
#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;}
1 0
- IPC之消息队列
- IPC之消息队列
- IPC之消息队列
- IPC之消息队列
- Linux IPC 之消息队列
- POSIX IPC之消息队列
- linux IPC之消息队列
- linux IPC之消息队列
- IPC之消息队列详解
- IPC(SystemV) 之 消息队列
- Linux IPC 之消息队列
- IPC之—消息队列
- IPC之 - .Net 消息队列(MSMQ) 使用
- Aix Unix IPC之消息队列
- 专题 12 IPC之消息队列
- Linux XSI IPC 之消息队列
- 进程通信 IPC 之消息队列
- linux IPC之POSIX消息队列
- android应用创建快捷方式
- 关于highcharts的封装和刷新
- struts2+spring+hibernate需要的jar包
- UVA437 The Tower of Babylon 动态规划
- 出现 java.util.ConcurrentModificationException 时的解决办法
- IPC之消息队列
- Eclipse 常用快捷键
- Eclipse 中双击变量不高亮 解决
- POJ3281--Dining(最大流)
- Web前端技术学习
- 小猿的第一个开源项目:办公自动化软件的通用开发模板 — OAer,简洁为美,轻量交互
- Java学习这七年
- XCode: 兼容ARC和non-ARC
- 一段封装mongodb连接的代码