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

相关推荐
ICscholar16 小时前
ExaDigiT/RAPS
linux·服务器·ubuntu·系统架构·运维开发
sim202017 小时前
systemctl isolate graphical.target命令不能随便敲
linux·mysql
米高梅狮子17 小时前
4. Linux 进程调度管理
linux·运维·服务器
再创世纪18 小时前
让USB打印机变网络打印机,秀才USB打印服务器
linux·运维·网络
fengyehongWorld19 小时前
Linux ssh端口转发
linux·ssh
知识分享小能手20 小时前
Ubuntu入门学习教程,从入门到精通, Ubuntu 22.04中的Shell编程详细知识点(含案例代码)(17)
linux·学习·ubuntu
Xの哲學21 小时前
深入解析 Linux systemd: 现代初始化系统的设计与实现
linux·服务器·网络·算法·边缘计算
龙月1 天前
journalctl命令以及参数详解
linux·运维
EndingCoder1 天前
TypeScript 的基本类型:数字、字符串和布尔
linux·ubuntu·typescript
YJlio1 天前
Kali Linux 外置无线网卡接入与识别排障(VMware 环境|合规学习版)
linux·网络·学习