linux高级学习8

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:为映射区的长度

相关推荐
秦jh_3 分钟前
【Linux】多线程(概念,控制)
linux·运维·前端
keep__go1 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求1 小时前
Linux中给普通账户一次性提权
linux·运维·服务器
Fanstay9851 小时前
在Linux中使用Nginx和Docker进行项目部署
linux·nginx·docker
大熊程序猿2 小时前
ubuntu 安装kafka-eagle
linux·ubuntu·kafka
daizikui4 小时前
Linux文件目录命令
linux·运维·服务器
NikitaC4 小时前
ldconfig 和 LD_LIBRARY_PATH 区别
linux·c++
清源妙木真菌4 小时前
Linux:进程概念
linux
许嵩664 小时前
IC 脚本之VIM 记录
linux·编辑器·vim