【Linux】消息队列--实现进程间通信

来源:互联网 发布:手机淘宝怎么退换货 编辑:程序博客网 时间:2024/06/06 01:51

定义:消息队列提供了一种从一个进程向另一个进程发送一个有类型数据块的方法。 

1. 创建新消息队列或取得已存在消息队列

原型:int msgget(key_t key, int msgflg);

参数:key:可以认为是一个端口号,也可以由函数 ftok 生成。

          msgflg:  IPC_CREAT:如果 IPC 不存在,则创建一个 IPC 资源,否则打开操作。

                         IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。

                         如果单独使用 IPC_CREAT,XXXget() 函数要么返回一个已经存在的共享内存的操作符,要么返回一个新建的共享内存的标识符。

                         如果将 IPC_CREAT 和 IPC_EXCL 标志一起使用,XXXget() 将返回一个新建的 IPC 标识符;如果该 IPC 资源已存在,或者返回-1。

                         IPC_EXEL 标志本身并没有太大的意义,但是和 IPC_CREAT 标志一起使用可以用来保证所得的对象是新建的,而不是打开已有的对象。

2. 向队列读/写消息

原型:msgrcv 从队列中取用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

          msgsnd 将数据放到消息队列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:msqid:消息队列的标识码。

          msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下:

struct msgstru{    long mtype; //大于0    char mtext[用户指定大小];};


       
 msgsz:消息的大小。

       msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。

       msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。如果 msgflg 和常数 IPC_NOWAIT 合用,则在 msgsnd() 执行时若是消息队列已满,则 msgsnd() 将不会阻塞,而会立即返回 -1,如果执行的是 msgrcv(),则在消息队列呈空时,不做等待马上返回 -1,并设定错误码为 ENOMSG。当 msgflg 为 0时,msgsnd() 及 msgrcv() 在队列呈满或呈空的情形时,采取阻塞等待的处理模式。

3. 设置消息队列属性

原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

参数:msgctl 系统调用对 msgqid 标识的消息队列执行 cmd 操作,系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID

          IPC_STAT :该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。

          IPC_SET :该命令用来设置消息队列的属性,要设置的属性存储在 buf 中。  

          IPC_RMID :从内核中删除 msqid 标识的消息队列。

使用消息队列进行进程间通信

(1)我们在这里将会编写两个程序,msgreceive msgsned 来表示接收和发送信息。根据正常的情况,我们允许两个程序都可以创建消息,但只有接收者在接收完最后一个消息之后,它才把它删除。

接收信息的程序源文件为 msgreceive.c  的源代码为:





发送信息的程序的源文件 msgsend.c  的源代码为: 




运行结果如下:




这里主要说明一下消息类型,注意 msgreceive.c 文件 main 函数中定义的变量 msgtype(注释为注意1),它作为 msgrcv 函数的接收信息类型参数的值,其值为0,表示获取队列中第一个可用的消息。msgsend.c 文件中 while 循环中的语句 data.msg_type = 1(注释为注意2),它用来设置发送的信息的信息类型,即其发送的信息的类型为1。所以程序 msgreceive能够接收到程序msgsend 发送的信息。


(2)下面我们再举一个有关进程间通信的例子,代码如下:



comm.h 的代码:



comm.c 的代码:





server.c 的代码:



client.c 的代码:



Makefile 的编写:




运行结果如下:



我们可以用命令查看和删除我们创建的消息队列,如下:



以上就是我关于消息队列的认识,希望对你有所帮助。




原创粉丝点击