罪恶克星 发表于 2024-8-28 15:50:51

【Linux】详解IPC:共享内存

目录
IPC
共享内存
1.明白
2.运用
1. 创建 ipc - shmget
2. 创建 key - ftok
⭕shmid vs key
3. 连接 - shmat
4. 脱离 - shmdt
5. 控制/删除 - shmctl
总结
代码示例
3.实行
comm.hpp
processa.cc
processb.cc
log.hpp
makefile
测试
4.思考

IPC

历程间通信 IPC有多种实现方式,包罗但不限于:

[*]管道(Pipes):包罗匿名管道和命名管道(FIFOs)。匿名管道只能在具有亲缘关系的历程之间使用,而命名管道可以用于任意历程间的通信。借助文件
[*]共享内存(Shared Memory):允许两个或多个历程访问同一块内存区域,从而实现快速的数据交换。借助物理内存映射
[*]消息队列(Message Queues):允许历程之间通过消息队列传递数据,消息可以是任意范例的数据,包罗文本和二进制数据。借助物理内存映射
[*]信号量(Semaphores):用于历程间的同步和互斥访问共享资源。信号量可以是二进制信号量(用于互斥访问)或计数信号量(用于资源的计数控制)。
[*]套接字(Sockets):通常用于网络通信,但在某些操作体系中也用于历程间通信。
[*]文件映射(Memory Mapped Files):允许历程通过内存地址来访问文件,从而实现历程间数据的共享。
每种IPC机制都有其优缺点,选择符合的IPC机制取决于具体的应用需求和场景。
本篇文章来学习systemv 共享内存:

[*]体系调用接口
[*]使用共享内存
[*]了解它的属性
共享内存

1.明白

历程间通信的本质是:先让不同的历程,看到同一份资源
共享内存区是最快的IPC形式


[*]

[*]一旦这样的内存映射到共享它的历程的地址空间,这些历程间数据传递不再涉及到内核
[*]换句话说是历程不再通过执行进入内核的体系调用来传递彼此的数据

留意:共享内存没有进行访问控制(同步与互斥)
如果要开释共享内存:1. 去关联 2. 开释共享内存
   上面的操作都是历程 直接 做吗?不是。直接由操作体系来做。
需求方 --体系调用--> 执行方
   操作体系如何管理共享内存呢?
先描述,再组织,内核结构体描述共享内存

https://i-blog.csdnimg.cn/direct/adde2904a209425f8d43c7c567031cc2.jpeg
   你怎么保证让不同的历程看到同一共享内存呢?你怎么知道这个共享内存存在照旧不存在呢?
设置了标识 key
2.运用

1. 创建 ipc - shmget

man shmget

https://img-blog.csdnimg.cn/img_convert/3dfde75bd534f28ca56328b735eaff5f.png
相当于传的就是:地址,大小,操作
功能:
创建一个新的共享内存段,或者获取一个已存在的共享内存段。
原型:
int shmget(key_t key, size_t size, int shmflg); 参数:


[*]key:共享内存段的标识符。用于命名共享内存段,在服务器和客户端之间共享。
[*]size:共享内存段的大小,建议是页大小(一样平常是4096字节)的整数倍。
[*]shmflg:权限标记和控制标记,可以组合使用:(如何实现操作?)


[*]

[*]IPC_CREAT:如果共享内存段不存在,则创建它;如果存在,则返回其标识符。
[*]IPC_CREAT | IPC_EXCL:如果共享内存段不存在则创建它;如果已存在,则返回错误。
[*]权限标记(如文件权限)给出访问权限(如 0666 表示用户、组、其他都可读写)。

返回值:
成功返回一个非负整数,即共享内存段的标识码(shmid);失败返回-1。
测试:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>

int main() {
    key_t key = 1234; // 任意选定一个key
    int shmid;

    // 创建共享内存段
    shmid = shmget(key, 4096, 0644 | IPC_CREAT);
    if (shmid == -1) {
      perror("shmget failed");
      exit(1);
    }

    printf("共享内存创建成功,ID: %d\n", shmid);
    return 0;
}
https://img-blog.csdnimg.cn/img_convert/d777c92fa78f74a9febb4c6e2b4b31cb.png
2. 创建 key - ftok

man ftok

https://img-blog.csdnimg.cn/img_convert/76b897eb811eb575d3f72bb0044ba0cb.png
功能:
用文件路径和项目ID创建一个System V IPC key。
原型:
key_t ftok(const char *pathname, int proj_id); 参数:


[*]pathname:路径名,指向一个存在且可访问的文件。
[*]proj_id:项目ID,通常为小整数。
返回值:
成功返回天生的 key;失败返回 -1。
测试:
#include <stdio.h>
#include <sys/ipc.h>
#include <stdlib.h>

int main() {
    key_t key;

    // 使用 ftok 生成一个唯一的key
    key = ftok("shmfile", 'R');
    if (key == -1) {
      perror("ftok failed");
      exit(1);
    }

    printf("ftok 生成的key: %d\n", key);
    return 0;
}
https://img-blog.csdnimg.cn/img_convert/c1b75a00e07f5e48210791b172e34d9a.png

页: [1]
查看完整版本: 【Linux】详解IPC:共享内存