深入理解进程间通信之消息队列(2)

  mtype成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型;mtext是消息内容,当然长度不一定为1。因此,对于发送消息来说, 首先预置一个msgbuf缓冲区并写入消息类型和内容,调用相应的发送函数即可;对读取消息来说,首先分配这样一个msgbuf缓冲区,然后把消息读入该缓冲区即可。

3、 获得或设置消息队列属性:

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

消息对列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. Linux为操作系统V进程间通信的三种方式(消息队列、信号灯、共享内存区)提供了一个统一的用户界面:

int ipc(unsigned int call, int first, int second, int third, void * ptr, long fifth);

第一个参数指明对IPC对象的操作方式,对消息队列而言共有四种操作:MSGSND、MSGRCV、MSGGET以及MSGCTL,分别代表向消息队列发送消息、从消息队列读取消息、打开或创建消息队列、控制消息队列;first参数代表唯一的IPC对象;下面将介绍四种操作。

int ipc( MSGGET, int first, int second, int third, void* ptr, long fifth);
与该操作对应的系统V调用为:int msgget( (key_t)first,second)。

int ipc( MSGCTL, int first, int second, int third, void* ptr, long fifth)
与该操作对应的系统V调用为:int msgctl( first,second, (struct msqid_ds*) ptr)。

int ipc( MSGSND, int first, int second, int third, void* ptr, long fifth);
与该操作对应的系统V调用为:int msgsnd( first, (struct msgbuf*)ptr, second, third)。

int ipc( MSGRCV, int first, int second, int third, void*ptr, long fifth);
与该操作对应的系统V调用为:int msgrcv( first,(struct msgbuf*)ptr, second, fifth,third),

注:本人不主张采用系统调用ipc(),而更倾向于采用系统V或者POSIX进程间通信API。原因如下:

虽然该系统调用提供了统一的用户界面,但正是由于这个特性,它的参数几乎不能给出特定的实际意义(如以first、second来命名参数),在一定程度上造成开发不便。

正如ipc手册所说的:ipc()是Linux所特有的,编写程序时应注意程序的移植性问题;

该系统调用的实现不过是把系统V IPC函数进行了封装,没有任何效率上的优势;

系统V在IPC方面的API数量不多,形式也较简洁。

3.系统V消息队列API

  系统V消息队列API共有四个,使用时需要包括几个头文件:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

1int msgget(key_t key, int msgflg)

参数key是一个键值,由ftok获得;msgflg参数是一些标志位。该调用返回与健值key相对应的消息队列描述字。

在以下两种情况下,该调用将创建一个新的消息队列:

如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;

key参数为IPC_PRIVATE;

参数msgflg可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。

调用返回:成功返回消息队列描述字,否则返回-1。

注:参数key设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。

2int msgrcv(int msgid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);

该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。

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

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