进程间通信(IPC)3 ------ 消息队列

来源:互联网 发布:excel查找不重复数据 编辑:程序博客网 时间:2024/05/18 21:38

      消息队列是一个存放在内核中的消息链表,由消息队列标识符标识。

      向消息队列发送消息时,必须组成合理的数据结构。Linux系统定义了一个模板数据结构msgbuf:

#include <linux/msg.h>struct msgbuf{      long mtype;      char mtext[1];};

      mtype字段代表消息类型。mtext字段指消息内容。


      消息队列是随着内核的存在而存在的,每个消息队列在系统范围内对应唯一的键值。要或得一个消息队列的描述符,只需提供该消息队列的键值即可,该键值通常由函数ftok返回。该函数原型:

#include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname,int proj_id);

      ftok函数根据pathname和proj_id这两个参数生成唯一的键值。pathname在系统中一定要存在且进程有权访问,参数proj_id的取值范围是1~255。执行成功会返回一个键值,失败返回-1。

      ftok返回的键值可以提供给函数msgget。msgget()根据这个键值创建一个新的消息队列或访问一个已存在的消息队列。msgget函数的原型:

#include <sys/msg.h>int msgget(key_t key, int msgflg);

      参数key即为ftok函数的返回值。msgflg是标志参数,一般取值IPC_CREAT,表示创建一个消息队列。

      创建消息队列后,就可以对消息队列进行读写了。函数msgsnd用于向消息队列发送(写)数据。

#include <sys/msg.h>int msgsnd(int msgid, struct msgbuf *msgp, size_t msgsz, int msgflg);

      上述函数向msgid标识的消息队列发送一个消息msgp。msgsz是消息的大小。msgflg为操作标志位。msgsnd函数成功返回0,失败返回-1。


      以下程序演示如何向消息队列发送消息:

#include <stdio.h>#include <stdlib.h>#include <sys/ipc.h>#include <sys/msg.h>#define BUF_SIZE256#define PROJ_ID32#define PATH_NAME"."//当前路径int main(void){/*用户自定义消息缓冲*/struct mymsgbuf {long msgtype;char ctrlstring[BUF_SIZE];} msgbuffer;intqid;    /*消息队列标识符*/intmsglen;key_tmsgkey;/*获取键值*/if((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1){perror ("ftok error!\n");exit (1);}/*创建消息队列*/if((qid = msgget (msgkey, IPC_CREAT|0660)) == -1){perror ("msgget error!\n");exit (1);}/*填充消息结构,发送到消息队列*/msgbuffer. msgtype = 3;strcpy (msgbuffer.ctrlstring , "Hello,message queue");msglen = sizeof(msgbuffer) - 4;//要发送的消息大小,不包含消息类型占用的4个字节if(msgsnd (qid, &msgbuffer, msglen, 0) == -1){perror ("msgget error!\n");exit (1);}exit(0);}

      运行上述程序,即向消息队列放入了一条消息,可以通过ipcs命令查看,执行结果如下: