您的位置:首页 > 其它

进程间通信之消息队列

2017-05-22 16:07 120 查看

消息队列

什么是消息队列?

消息队列其实就是提供了一种从一个进程向另一个进程发送一个数据块的方法。 我们可以通过发送消息来避免命名管道的同步和阻塞问题。此外,消息队列和管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列不一定是先入先出。消息队列与命名管道有一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)。



内核为每一个IPC对象都维护了一个数据结构



消息队列,信号量和共享内存都有这样一个共同的数据结构。

而消息队列的结构则是



可以看到第一个条目就是IPC结构体,即是共有的,后面都是消息队列私有的成员。

消息队列是通过链表实现的。

实现消息队列需要的函数

1.创建新消息队列或者获取已有的消息队列



其中,key可以认为是一个端口号,由函数ftok()创建,原型如下:



而msgflg则是一个标识,IPC_CREAT 如果IPC不存在,则创建一个IPC资源,否则打开操作;IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。

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

2.向队列读或写消息

①msgrcv()从队列中获取消息

②msgsnd()往队列中放数据



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

struct msgstru{

long mtype; //大于0

char mtext[用户指定大小];

};

msgsz是指消息的大小。

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

msgflg是用来指明核心程序在队列没有数据的情况下所应采取的行动。默认为0。

3.设置消息队列属性



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

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


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

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

下面我们就去学习如何实现消息队列

模拟实现消息队列

首先这是comm.h的代码:



然后是comm.c去实现头文件中定义的代码:



模拟实现完消息队列后,我们需要去测试一下:

发送端client.c



接收端server.c



然后我们运行代码:





运行两个程序,然后在client这端输入,然后就会在server这端显示;





然后在server这端在随便输入一个,那么client这端就会接收到信号,然后就可以继续往其中输入了,然后就会再在server这端显示出来。

以上就是消息队列的模拟实现了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: