24.9.4学习目录
一.消息队列
消息队列存放在内存中,有内核维护
消息队列特点:
- 消息队列中的消息是有类型的
- 消息是有格式的
- 消息队列可以实现消息的随机查询,编程时可以按照消息的类型读取
- 允许一个或者多个进程向其写入或读取
- 当从消息队列中读取消息后,消息会被删除
- 每个消息队列都有一个唯一的消息队列标识符
- 只有内核重启或人工删除消息队列时,消息队列才会被删除
1.消息队列API
(1)获取系统的唯一的key值
提供IPC通信机制需要一个key值,通过key值就可以在系统中获取一个唯一的消息队列标识符,key值可以认为指定,也可以通过ftok函数获取
cpp
#include<sys/types.h>
#include<sys/ipc.h>
//参数为路径名pathname,和项目ID,proj_id
key_t ftok(const char *pathname,int proj_id)
(2)创建消息队列
cpp
#include <sys/msg.h>
//通过key值和msgflg创建消息队列,当key值相同返回的消息队列的标识符就相同
int msgget(key_t key,int msgflg);
msgflg的取值:
IPC_CREAT:创建消息队列
IPC_EXCL:检测消息队列是否存在
位或权限位:设置消息队列的访问权限,格式和open函数的mode_t相同(即为0666等)
(3)查看消息队列
cpp
//在控制界面输入
ipcs -q
(4)删除消息队列
cpp
ipcrm -q 队列ID
(5)消息队列的的信息格式
cpp
typedef struct 名字
{
//消息类型,必须为第一个,并且类型也是为long
long mtype;
//消息正文
char mtext[100];
.........
}别名;
(6)发送消息
cpp
#include <sys/msg.h>
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
msqid:消息队列标识符
msgp:待发送消息结构体的地址
msgsz:消息正文的字节数(通过其来获取sizeof(结构体名)- sizeof(long))
msgflg:函数的控制属性
0:msgsnd调用阻塞直到条件满足为止
IPC_NOWAIT:若消息没有立即发送则调用该函数的进程会立即返回
(7)接受消息
cpp
#include <sys/msg.h>
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
msqid:消息队列的标识符
msgp:存放消息结构体的地址
msgsz:消息正文的字节数
msgtyp:消息的类型,当有多个相同类型的消息,采用先进先出原则
msgtyp = 0:返回队列中的第一个消息
msgtyp > 0:返回队列中消息类型为msgtyp的消息
msgtyp < 0:返回队列中消息类型小于或者等于msgtyp的消息,如果消息有多个,则取类型最小的消息
msgflg:函数的控制属性,只有0、MSG_NOERROR和IPC_NOWAIT
(8)消息队列的控制
cpp
#include <sys/msg.h>
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
cmd:函数功能的控制
buf:msqid_ds数据类型的地址,用于存放或更改消息队列的属性
cmd:函数功能的控制
IPC_RMID:删除消息队列
IPC_STAT:将消息队列相关的数据结构中的值,存放到buf指向的结构中
IPC_SET:将buf指向的值复制给消息队列
二.mmap存储映射
其是将磁盘文件与程序中一个缓冲区进行映射,对缓冲区进行操作即相当于对磁盘文件进行操作,其使用地址(指针)完成I/O操作
1.mmap的API
(1)建立映射区
cpp
#include <sys/mman.h>
//成功返回映射区的首地址
void *mmap(void *addr,size_t length,int prot,int flags.int fd,off_t offset);
addr:地址,填写null
length:映射区的长度,要与磁盘文件相同
prot:权限,有PORT_READ(可读)、PROT_WRITE(可写)
flags:标志位,有MAP_SHARED(共享的)对映射区的修改会影响文件、MAP_PRIVATE(私有的)
fd:文件描述符
offset:指定其偏移量
(2)拓展文件大小
因为一个新打开的文件是没有大小,这会导致映射区无法写入
cpp
//path为拓展的文件,length为需拓展的大小
int truncate(const char *path,off_t length);
(3)释放映射区域
只能释放本进程中的映射
cpp
int munmap(void *addr,size_t length);
addr:为映射区的首地址
length:为映射区的长度