锁定老帖子 主题:Linux消息队列操作
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-09
最后修改:2009-03-09
对消息队列的操作无非有下面三种类型: 1、 打开或创建消息队列 注:消息队列描述字是由在系统范围内唯一的键值生成的,而键值可以看作对应系统内的一条路经。 2、 读写操作 消息读写操作非常简单,对开发人员来说,每个消息都类似如下的数据结构: struct msgbuf { long mtype; char mtext[1]; };
mtype成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型;mtext是消息内容,当然长度不一定为1。因此,对于发送消息来说,首先预置一个msgbuf缓冲区并写入消息类型和内容,调用相应的发送函数即可;对读取消息来说,首先分配这样一个msgbuf缓冲区,然后把消息读入该缓冲区即可。 3、 获得或设置消息队列属性: 消息队列的信息基本上都保存在消息队列头中,因此,可以分配一个类似于消息队列头的结构(struct msqid_ds,见附录 2),来返回消息队列的属性;同样可以设置该数据结构。
消息队列API
1、文件名到键值
#include <sys/types.h> #include <sys/ipc.h> key_t ftok (char*pathname, char proj); 它返回与路径pathname相对应的一个键值。该函数不直接对消息队列操作,但在调用ipc(MSGGET,…)或msgget()来获得消息队列描述字前,往往要调用该函数。典型的调用代码是: key=ftok(path_ptr, 'a'); ipc_id=ipc(MSGGET, (int)key, flags,0,NULL,0); …
2.系统V消息队列API #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
1)int msgget(key_t key, int msgflg) 参数key是一个键值,由ftok获得;msgflg参数是一些标志位。该调用返回与健值key相对应的消息队列描述字。 在以下两种情况下,该调用将创建一个新的消息队列:
参数msgflg可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。 调用返回:成功返回消息队列描述字,否则返回-1。 注:参数key设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。 2)int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg); msqid为消息队列描述字;消息返回后存储在msgp指向的地址,msgsz指定msgbuf的mtext成员的长度(即消息内容的长度),msgtyp为请求读取的消息类型;读消息标志msgflg可以为以下几个常值的或:
msgrcv手册中详细给出了消息类型取不同值时(>0; <0; =0),调用将返回消息队列中的哪个消息。 msgrcv()解除阻塞的条件有三个:
调用返回:成功返回读出消息的实际字节数,否则返回-1。 3)int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg); 对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:
调用返回:成功返回0,否则返回-1。 4)int msgctl(int msqid, int cmd, struct msqid_ds *buf);
调用返回:成功返回0,否则返回-1。 ---------------------------------------------------------------------------------------------------------------------- /*msgserver.c*/ #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/stat.h> #define MSG_FILE "msgserver.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR /* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */ /* ipcrm -q <msqid> */ struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main() { struct msgtype msg; key_t key; int msgid; if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\n", strerror(errno)); exit(1); } if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1) { fprintf(stderr, "Creat Message Error:%s\n", strerror(errno)); exit(1); } printf("msqid = %d\n", msgid); while(1) { msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0); fprintf(stderr,"Server Receive:%s\n", msg.buffer); msg.mtype = 2; msgsnd(msgid, &msg, sizeof(struct msgtype), 0); } exit(0); }
/* msgclient.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/stat.h> #define MSG_FILE "msgserver.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main(int argc, char **argv) { struct msgtype msg; key_t key; int msgid; if(argc != 2) { fprintf(stderr,"Usage:%s string\n", argv[0]); exit(1); } if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\n", strerror(errno)); exit(1); } if((msgid=msgget(key, PERM))==-1) { fprintf(stderr,"Creat Message Error:%s\n", strerror(errno)); exit(1); } msg.mtype = 1; strncpy(msg.buffer, argv[1], BUFFER); msgsnd(msgid, &msg, sizeof(struct msgtype), 0); memset(&msg, '\0', sizeof(struct msgtype)); msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0); fprintf(stderr, "Client receive:%s\n", msg.buffer); exit(0); }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 5562 次