进程间通信(2)——消息队列

【3】消息队列(报文队列) (1)概述

消息队列是在消息传递过程中保存消息的容器。它是一种以链表式结构组织的一组数据,存放在内核中,由各进程通过消息队列标识符来引用,在消息队列中可以随意根据特定的数据类型值来检索消息

消息队列就是一个消息的链表。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息,包括消息队列键值、用户ID、消息队列中消息数目等等,甚至记录了最近对消息队列读写进程的ID。用户可以访问这些信息,也可以设置其中的某些信息。

结构msg_queue用来描述消息队列头,存在于系统空间,定义如下:

进程间通信(2)——消息队列

结构msqid_ds用来设置或返回消息队列的信息,存在于用户空间,定义如下:

进程间通信(2)——消息队列

消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的引用标识符(ID)——即创建或打开消息队列,只需提供该消息队列的键值即可。

(2)获得特定文件名键值的系统调用是ftok,函数原型如下: #include <sys/types.h> #include <sys/ipc.h> key_t ftok(char *pathname,char proj);

返回:若成功返回消息队列的一个键值,若失败返回-1
(在调用msgget()来获得消息队列标识符前,往往调用该函数)

(3)创建或打开一个消息队列的系统调用为msgget,函数原型如下: #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key,int msgflg);

返回:若成功则返回与键值key相对应的消息队列标识符(ID),若失败返回-1

参数key是一个键值,由ftok获得

msgflg参数是一些标志位,可以取以下值:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的逻辑或结果

(4)消息队列的读写

使用消息队列进行进程间通信,就是要对消息队列进行读和写操作

写操作即是向消息队列中发送数据,读操作就是从消息队列中读走数据

消息队列所传递的消息由两部分组成,即消息的类型所传递的数据

一般用数据结构struct msgbuf来表示,通常消息类型是一个正的长整数,而数据则根据需要设定。

设定一个传递1024字节长度的消息可将结构定义如下:

struct msgbuf { long msgtype; char msgtext[1024]; };

msgtype:消息类型

msgtext:消息内容

因此,对于发送消息来说,首先预置一个msgbuf缓冲区并写入消息的类型和内容,调用相应的发送函数即可;对读消息来说,首先分配这样一个msgbuf缓冲区,然后把消息读入该缓冲区即可。

(5)向消息队列中发送数据:msgsnd

函数原型:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgsnd(int msqid,const void *prt,size_t nbytes,int flags);

返回:成功返回0,出错返回-1

msgsnd函数的作用是向一个消息队列发送一个消息,该消息被添加到队列的末尾

参数msqid代表消息队列的引用标识符(ID)

参数prt是一个void类型指针,指向要发送的消息

参数nbytes是以字节表示的消息的数据长度

参数flags用于指定消息队列满时的处理方法

(6)从消息队列接收数据:msgrcv #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgrcv(int msqid,void *prt,size_t nbytes,long,type,int flags);

返回:成功返回消息的数据长度,出错返回-1

此函数用于从指定的消息队列中读取一个消息数据

参数msqid代表消息队列的引用标识符

prt是一个void类型指针,指向存放消息的缓冲区

参数nbytes是以字节表示的要接收消息的数据长度

参数flags用于指定消息队列满时的处理方法

(7)获得或设置消息队列属性(msgctl)

消息队列信息基本上都保存在消息队列头中,因此,可以分配一个类似于消息队列头的结构struct msqid_ds来返回消息队列的属性;同样可以设置该数据结构。

关于消息队列属性的操作的系统调用如下:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid,int cmd,struct msqid_ds *buf);

返回:若成功返回0,否则返回-1

(8)下面的例子基本上涵盖了对消息队列的所有操作,msg_app.c

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxgdd.html