今晚来整理一下消息队列,消息队列是一条由消息连接而成的链表,存在内核里面,通过消息对了的引用标识符来访问,每个消息队列都有一个msqid_ds结构与之对应,这个结构保存了消息队列的当前状态参数,这个结构的定义如下:
1 steuct msqid_ds
2 {
3 struct ipc_perm msg_perm;
4 struct msg *msg_first;
5 struct msg *msg_last;
6 ulong msg_ctypes;
7 ulong msg_qnum;
8 ulong msg_qbytes;
9 pid_t msg_lspid;
10 pid_t msg_lrpid;
11 time_t msg_stime;
12 time_t msg_rtime;
13 time_t msg_ctime;
14 }
这个结构每个域都有相关的定义,下面来述说一下消息队列 的具体内容:
1,创建或打开消息队列的操作
通过系统函数的调用,可以创建或者打开消息队列,把一个消息发送到消息队列中以及从消息队列中获取消息,首先来看打开消息队列 的函数
#include <sys/types.h0>
#include <sys/ipc.h>
#include <sys/msq.h>
int message(key_t key,int flag);
这个函数可以创建一个新的消息队列也可以打开一个已经存在的消息队列,这取决于key和flag的值,函数执行成功时会返回消息队列的引用标识符,否则返回-1,而当一个新的消息队列创建时,与之对应的msqid_ds结构也会被初始化,这里不具体说明了,下面举个例子来说明。
例:下列程序根据相关用户输入关键字,以权限-rw-rw---创建或打开一个消息队列,代码如下:
msgget.c
2,发送和接受消息
消息队列有发送消息和接受消息两种操作,进程通过这两种操作实现进程间的通信。
发送消息分的函数说明如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <int msqid,const void *ptr,size_t nbytes,int flag>;
//msqid消息队列的引用标识符。新发送的消息插入到消息队列的末尾
//ptr指向一个长正整数的指针,这个正整数之后紧跟消息队列中所传递的数据
//nbytes消息的长度,不包含在长正整数在内,以字节记
//flag可以取0或者IPC_NOWAIT
函数返回成功为0,否则为-1。
接受消息的函数说明如下:
#include <sys/yypes.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include (int msqid,void *ptr,size_t nbytes,long type,int flag);
//msqid消息队列的引用标识符。
//ptr指向一个长正整数的指针,这个正整数之后紧跟消息队列中所传递的数据
//nbytes要接收消息数据的长度,以字节记
//type这个参数用来指定要接受队列中的那条信息
//flagflag中的两位与接收消息有关
现在可以编写用消息队列进行通信的程序了,编写两个程序,一个接收一个发送,代码如下:
接收msgrcv
发送msgsnd
两个程序运行的结果如下:
$./发送magsnd
Enter some text:hello
Enter some text:world
Enter some text:end
$./接收msgrcv
You wrote:hello
You wrote:world
You wrote:end
从这个例子当中,可以看出,通信的进程可以是完全无关的两个进程,不需要约定同步分方法。
3,控制消息进程
msgctl函数用于对消息队列进行控制,它的原型如下:
#include <sys/msg.h>
#include (int msqid,int cmd,struct msqid_ds *buf);
msgctl函数对msqidl函数指定的消息队列执行参数cmd要求的控制操作,参数msqid是一个正整数,它必须由msgget返回的消息队列的id
下面来句一个例子总结说明消息队列,代码如下:
Msg.c