当前位置: 首页 > news >正文

System V通信机制

IPC对象概述

IPC对象消息队列共享内存信号量
特点多对多共享数据具备阻塞的全局变量

在这里插入图片描述

设置流程

  1. 获取IPC对象key
  2. xxxget//获取对象ID值
  3. xxxctl//操作函数
  4. 相对独立的操作函数

IPC相关bash命令

ipcs [-参数]
>-a:显示所有 IPC 设施(默认选项)。
>-q:仅显示消息队列。
>-m:仅显示共享内存段。
>-s:仅显示信号量。
>-l:显示 IPC 资源的系统限制。
>-u:显示 IPC 设施的汇总信息。
>-p:显示与 IPC 设施相关的进程 ID。
>-t:显示时间信息,如上次操作时间。
>-c:显示创建者的用户和组信息。
>-b:显示 IPC 设施的权限和大小信息。ipcrm -[参数]#在bash中删除IPC对象
> -m, --shmem-id <id>        remove shared memory segment by id
> -M, --shmem-key <key>      remove shared memory segment by key
> -q, --queue-id <id>        remove message queue by id
> -Q, --queue-key <key>      remove message queue by key
> -s, --semaphore-id <id>    remove semaphore by id
> -S, --semaphore-key <key>  remove semaphore by key
> -a, --all[=shm|msg|sem]    remove all (in the specified category)
> -v, --verbose              explain what is being done
> -h, --help                 display this help
> -V, --version              display version

消息队列

在这里插入图片描述

1.创建key

函数原型key_t ftok(const char *pathname, int proj_id);
头文件#include <sys/ipc.h>
参数pathname:指向一个已存在文件的路径字符串,key:一个 8 位的项目标识符(范围 0-255)
返回值成功返回key_t类型,失败返回*-1*

2.创建对象

函数原型int msgget(key_t key, int msgflg);
头文件#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
参数key:由 ftok msgflg:标志位,用于指定队列的权限和创建行为
返回值成功时返回消息队列的标识符(非负整数)。失败时返回 -1
msgflg
IPC_CREATIPC_CREAT:如果队列不存在,则创建。
IPC_EXCL与 IPC_CREAT 一起使用,确保队列不存在时创建,否则返回错误。
权限模式IPC_CREAT|0666:在创建时同时复制权限

3.进行发送

函数原型int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
头文件#include <sys/msg.h>
参数msqid:消息队列标识符,由 msgget 函数返回。msgp:指向消息缓冲区的指针,缓冲区需包含消息类型和消息内容。msgsz:消息正文的大小(以字节为单位),不包括消息类型字段;msgflg:控制标志,通常为 0(阻塞模式)或 IPC_NOWAIT(非阻塞模式)。
返回值成功时返回 0,失败时返回 -1 并设置 errno。
msgflag
IPC_NOWAIT非阻塞模式
0进行阻塞

在创建根据手册描述需要创建一个包含正文,和类型的结构体

struct msgbuf {long mtype;     // 消息类型,必须为正整数char mtext[1];  // 消息正文,实际使用时需自定义长度
};

示例

typedef struct msgbuf
{long mtype;       /* message type, must be > 0 */char mtext[1024];    /* message data */
}msgbuf;int main(void)
{key_t key = ftok(".", 123);//在当前路径下创建生成一个"钥匙"int mag_id = msgget(key, IPC_CREAT | 0664);//创建一个新的消息队列msgbuf my_msbuf;my_msbuf.mtype = 100;memset(my_msbuf.mtext, 0, sizeof(my_msbuf.mtext));scanf("%s", my_msbuf.mtext);msgsnd(mag_id, &my_msbuf, strlen(my_msbuf.mtext), 0);//进行阻塞的发送信息return 0;
}

运行结果
在这里插入图片描述

4.进行接收

函数原型int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
头文件#include <sys/msg.h>
参数msqid:消息队列标识符,由 msgget 创建。msgp:通常是一个结构体,包含消息类型和消息正文。msgsz:消息正文的大小msgtyp:指定接收的消息类型;msgflg:控制行为的标志位
返回值成功时返回实际接收的消息正文的字节数。失败时返回 -1,并设置 errno。
msgflag
IPC_NOWAIT如果没有符合条件的消息,立即返回错误(不阻塞)
MSG_NOERROR如果消息正文超过 msgsz,截断消息而不报错。
0进行阻塞

示例

int main(void)
{key_t key = ftok(".", 123);//在当前路径下创建生成一个"钥匙"int mag_id = msgget(key, IPC_CREAT|0664);//创建一个新的消息队列msgbuf my_msbuf;my_msbuf.mtype = 200;while (1){memset(my_msbuf.mtext, 0, sizeof(my_msbuf.mtext));msgrcv(mag_id, &my_msbuf, sizeof(my_msbuf.mtext), 100, MSG_NOERROR);//进行阻塞的发送信息printf("2接收到程序:%s\n", my_msbuf.mtext);}
}

运行结果
在这里插入图片描述

5.操作消息队列

函数原型int msgctl(int msqid, int cmd, struct msqid_ds *buf);
头文件#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
参数msqid:消息队列的标识符,由 msgget 函数创建或获取。cmd:控制命令;buf:指向 struct msqid_ds 的指针,用于存储或设置消息队列的属性。
返回值成功时返回 0。失败时返回 -1,并设置 errno 以指示错误类型。

属性信息结构体struct msqid_ds

struct msqid_ds {struct ipc_perm msg_perm;  // 权限信息time_t msg_stime;          // 最后发送消息的时间time_t msg_rtime;          // 最后接收消息的时间time_t msg_ctime;          // 最后修改时间unsigned long __msg_cbytes; // 当前队列中的字节数msgqnum_t msg_qnum;        // 当前队列中的消息数msglen_t msg_qbytes;       // 队列的最大字节数pid_t msg_lspid;           // 最后发送消息的进程 PIDpid_t msg_lrpid;           // 最后接收消息的进程 PID
};

常用命令

cmd
IPC_STAT获取消息队列的属性,存储到 buf 指向的结构体中
IPC_SET设置消息队列的属性,从 buf 指向的结构体中读取
IPC_RMID立即删除消息队列,忽略 buf 参数

示例

int main(void)
{key_t key = ftok(".", 123);//在当前路径下创建生成一个"钥匙"int mag_id = msgget(key, IPC_CREAT | 0664);//创建一个新的消息队列msgbuf my_msbuf;my_msbuf.mtype = 100;struct msqid_ds msginfo;msgctl(mag_id, IPC_STAT,&msginfo);printf("信息数量:%lu\n", msginfo.msg_qnum);return 0;
}

运行结果
在这里插入图片描述

消息队列是流操作


共享内存

在这里插入图片描述

1.创建创建key

创建key与消息队列相同,这里就不过多赘述

*2.创建shareMemoryID

函数原型int shmget(key_t key, size_t size, int shmflg);
头文件#include <sys/ipc.h> #include <sys/shm.h>
参数key:共享内存段的键值,通常由 ftok 生成或直接使用 IPC_PRIVATE。size:共享内存段的大小,通常是4096的倍数。如果是获取已存在的共享内存,此参数可设为 0。shmflg:权限标志
返回值成功时返回共享内存段的标识符(非负整数)。失败时返回 -1,并设置 errno 表示错误原因。

shmflg

shmflg
IPC_CREAT创建,可以与限权相或进行设置
IPC_EXCL确保在创建新的 IPC 资源(如共享内存、消息队列或信号量)时,如果该资源已存在,则创建操作会失败。

3.映射内存

函数原型void *shmat(int shmid, const void *shmaddr, int shmflg);
头文件#include <sys/shm.h>
参数shmid:共享内存标识符,由 shmget 调用返回;shmaddr:指定共享内存附加到进程地址空间的位置。通常设为 NULL,由系统自动选择地址。shmflg:附加标志,例如 SHM_RDONLY 表示只读访问。
返回值shmat 返回共享内存附加到进程地址空间的起始地址。失败时,返回 (void *)-1,并设置 errno 以指示错误原因。

shmflg

shmflg
0默认,代表共享内存可读可写。
SHM_RDONLY代表共享内存只读。

示例

int main(void)
{key_t key = ftok(".", 1);//在当前路径下创建生成一个"钥匙"if(key == -1){perror("ftok sailed\n");}int shm_ID = shmget(key, 4096, IPC_CREAT|0664);if (shm_ID == -1) {perror("shmget failed\n");exit(1);}int shmdt(const void *shmaddr);char * add = shmat(shm_ID, NULL, 0);sprintf(add, "1234");printf("%s", add+1);return 0;
}

执行结果
在这里插入图片描述

操作

函数原型int shmctl(int shmid, int cmd, struct shmid_ds *buf);
头文件#include <sys/ipc.h> #include <sys/shm.h>
参数shmid:指定的共享内存的ID;cmd:一些命令字;buf:用来存放共享内存信息的结构体
返回值失败返回-1

cmd参数说明

cmd
IPC_STAT将共享内存的当前状态信息复制到 buf 指向的 shmid_ds 结构中。调用者需具备读权限。
IPC_SET通过 buf 修改共享内存的权限、所有者或时间戳等字段。仅超级用户或有效用户 ID 与共享内存所有者/创建者匹配的用户可执行。
IPC_RMID标记共享内存段为待销毁状态。实际销毁会在最后一个附加进程分离后发生。此操作需超级用户或有效用户 ID 匹配所有者/创建者。
http://www.lryc.cn/news/622385.html

相关文章:

  • Web攻防-大模型应用LLM安全提示词注入不安全输出代码注入直接间接数据投毒
  • Go语言 time 包详解:从基础到实战
  • Vue模板引用(Template Refs)全解析1
  • 介绍大根堆小根堆
  • 命令模式C++
  • 【DSP28335 事件驱动】唤醒沉睡的 CPU:外部中断 (XINT) 实战
  • AI - MCP 协议(一)
  • 备忘录模式C++
  • 线性代数 · 直观理解矩阵 | 空间变换 / 特征值 / 特征向量
  • JavaScript递归
  • nVidia Tesla P40使用anaconda本地重编译pytorch3d成功加载ComfyUI-3D-Pack
  • 磁悬浮轴承“幽灵振动”克星:深度解析同频振动机理与精准打击策略
  • 日常反思总结
  • Layui 语法详解与全功能示例
  • GoLand深度解析:智能开发利器与cpolar内网穿透的协同革命
  • 基于Spring Boot的智能民宿预订与游玩系统设计与实现 民宿管理系统 民宿预订系统 民宿订房系统
  • Linux操作系统从入门到实战(二十二)命令行参数与环境变量
  • Lecture 10: Concurrency 3
  • 【嵌入式硬件实例】-555定时器驱动直流无刷电机
  • kubernetes(序)
  • ESP32-C3_TCP
  • Windows Server存储智能数据校验
  • Spring Boot接口签名校验设计与实现
  • 办公效率提升指南:完成重复任务自动化
  • Docker Compose 入门教程
  • 图片滤镜处理(filters)
  • lidar2imu/auto_caliban以及manual_calib安装过程
  • 线程P5 | 单例模式[线程安全版]~懒汉 + 饿汉
  • 【C#补全计划】委托
  • Vue 侦听器(watch 与 watchEffect)全解析2