IPC-消息队列
2017-06-18 19:26
176 查看
消息队列
消息队列是消息的链式队列,提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块都有一个特定的类型,接收者进程接受的数据块可以有不同的类型值。特点
依赖于操作系统的IPC模块
可以进行进程间的双向通信
消息队列是基于消息的,管道是基于字节流的
消息队列不一定是先入先出
消息队列的每个消息的长度是有上限的,总的字节数是有上限的,系统的上消息队列的总数有上限。
消息队列的两种数据结构
msqid_ds:标识整个消息队列的基本情况,主要包括整个消息队列的权限,拥有者和操作权限。还有两个指针分别指向消息队列的第一个消息和最后一个消息。msg:整个数据队列的主体,一个消息队列有若干个消息,每个消息队列的属性有消息类型,消息大小,消息内容指针和下一个消息数据结构的位置。
消息队列模型
消息队列管理函数
创建消息队列#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key, int msgflg); //创建新消息队列或取得已存在的消息队列 第一个参数key是有ftork()创建的。第二个参数msgflg的对位用来确定消息队列的访问权限 If msgflg specifies both IPC_CREAT and IPC_EXCL and a message queue already exists for key, then msgget() fails with errno set to EEXIST. (This is analogous to the effect of the combination O_CREAT | O_EXCL for open(2).) //IPC_CREAT:如果ipc不存在就创建一个,否则就打开 //IPC_EXCL:如果key存在,就返回失败 //如果将IPC_SREAT和IPC_EXCL标志一起使用,新建一个ipc资源,如果存在则返回-1
2.消息队列属性控制
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf); //创建消息队列后,对消息队列的属性进行修改 //msqid消息队列的标识符,是使用msgget的返回值 //cmd要执行的操作 //3种cmd操作.IPC_STAT该命令用来获取消息队列的msqid_ds数据结构,并将其保存在buf指向的结构中。IPC_SET该命令用来设置消息队列的属性,要设置的属性保存在buf中。IPC_RMID:从内核中删除msqid
3.向队列中读写消息
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); //将新的消息添加到消息队列尾端。 //参数msqid为msgget的返回值, //msgp为指向的用户定义的缓冲区 struct msgbuf { long mtype;//消息类型 char mtext[1]; //消息内容 }; //msgsz为接受消息的大小 //msgflg用来指定在到达系统为消息队列所定的界限(如达到的字数限制)时应采取的操作。如果设置为IPC_NOWAIT,如果执行的是msgsnd()消息队列满时,不会阻塞,立即返回-1。如果执行的是msgrcv,消息队列为空是,立即返回并设置错误码是ENOMSG。 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); //用于从队列中取消息。 //msqid表示从哪个消息队列中取消息 //msgp一个临时消息的数据结构,用来保存读取的消息 struct msgbuf { long mtype;//消息类型 char mtext[1]; //存储消息位置,需要重新定义 }; //msgsz用于指定mtext的大小 //msgtyp用于指定请求消息的类型,=0收到队列的第一条消息,任意类型;>0收到第一条msgtyp类型的消息;<0收到第一条最低类型(小于或等于msgtyp的绝对值)的消息 //msgflg用来指定在到达系统为消息队列所定的界限(如达到的字数限制)时应采取的操作。如果设置为IPC_NOWAIT,如果执行的是msgsnd()消息队列满时,不会阻塞,立即返回-1。如果执行的是msgrcv,消息队列为空是,立即返回并设置错误码是ENOMSG
代码实现
//msg_receiver.c #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/msg.h> #include<sys/ipc.h> struct data { long msg_type; char msg_text[512]; }; int main() { int msgid; struct data msg_data; if(msgid=msgget((key_t)1234,0666|IPC_CREAT)==-1) { perror("msgget"); return 1; } while(1) { if(msgrcv(msgid,&msg_data,512,(long)0,0)==-1) { perror("msgrcv"); return 2; } printf("A receive:%s\n",msg_data.msg_text); printf("A send"); memset(msg_data.msg_text,0,sizeof(msg_data.msg_text)); fgets(msg_data.msg_text,512,stdin); if(msgsnd(msgid,&msg_data,512,0)==-1) { perror("msgsnd"); return 3; } if(strncmp(msg_data.msg_text,"end",3)==0) { printf("A end\n"); break; } } if(msgctl(msgid,IPC_RMID,0)==-1) { perror("msgctl"); return 4; } return 0; }
//msg_sender.c #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #define MAX_TEXT 512 struct data { long my_msg_type; char msg_text[MAX_TEXT]; }; int main() { struct data some_data; int msgid; key_t key=ftok(".",88); if(msgid=msgget(key,0666|IPC_CREAT)==-1) { return 1; } while(1) { printf("B send:"); fgets(some_data.msg_text,512,stdin); if(msgsnd(msgid,&some_data,MAX_TEXT,0)==-1) { perror("msgsnd"); return 2; } if(strncmp(some_data.msg_text,"end",3)==0) { break; } memset(some_data.msg_text,0,sizeof(some_data.msg_text)); if(msgrcv(msgid,&some_data,MAX_TEXT,(long)0,0)==-1) { perror("msgrcv"); return 3; } printf("B receive:%s\n",some_data.msg_text); if(strncmp(some_data.msg_text,"end",3==0)) { printf("B end"); break; } } }
相关文章推荐
- 进程间通信(IPC)——信号量、共享内存、消息队列
- IPC--消息队列
- IPC实现机制(三)---消息队列
- linux ipc—消息队列
- Android IPC 进程间通信机制之 Messenger
- Android IPC -- 初期(实现多进程模式)
- Linux — IPC通信之共享内存
- codechef T4 IPC Trainers
- Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用
- IPC的7中通信方式
- 细说linux IPC(四):posix 共享内存
- Android开发艺术探索_IPC机制(二)
- linux IPC---记录上锁
- IPC进程间通信
- ipc(一)无名管道示例
- IPC机制系列之二 IPC机制的基础概念Serializable、Parcelable以及Binder
- 进程IPC---管道和有名管道
- IPC-(进程间通信)-实现方式
- 进程间通信(IPC)介绍
- android进程间通信ipc Socket (二)