系统编程-共享内存

共享内存

目录

共享内存

引入

一、使用指令查看共享内存

二、使用共享内存进行通信的步骤

1、获取键值

2、创建或获取共享内存 id

3、映射共享内存到进程的地址空间

4、进行数据的写入和读取        

 -- memcpy

5、对“块”进行赋值操作

5、解除映射

6、共享内存的多种操作函数


引入

  • system V中进程间通信的一种方式

  • 是速度最快的,但是缺少同步机制,就是两个进程间不知道对方什么时候读,什么时候写。

-- 共享内存缺少同步机制指的是在多个进程或线程访问同一块内存区域时,这些进程或线程之间缺乏协调和控制,从而可能导致数据一致性问题或竞争条件。

  • 可以理解共享内存为一个系统级别的数组,可以当作数组进行操作

一、使用指令查看共享内存

  • ipcs -m 

    alt text

  • shmid:共享内存的 id

  • 字节:共享内存的大小

  • 连接数:有几个进程正在使用共享内存

二、使用共享内存进行通信的步骤

alt text

 

        -- 进程无法直接对共享内存进行操作。共享内存的工作原理是通过将物理内存区域映射到进程的虚拟地址空间来实现的。当多个进程需要访问共享内存时,它们首先需要执行映射操作,

1、获取键值

(1)函数获取:

-- 函数头文件

  • #include <sys/types.h>
  • #include <sys/ipc.h>

-- 函数原型

  • key_t ftok(const char *pathname, int proj_id)

-- 函数的作用:

  • 通过传入的参数来获取指定的键值

-- 函数的参数:

  • pathname:必须是存在的路径
  • proj_id:0~255

-- 函数的返回值:

  • 会根据函数的参数来返回一个键值

(2)自己定义:

  • #define my_key 0x12345678

-- 键值的作用:

  • 一样的键值可以让不同进程来获取到同一个消息队列的id号

2、创建或获取共享内存 id

-- 函数头文件

  • #include <sys/ipc.h>
  • #include <sys/shm.h>

-- 函数原型

  • int shmget(key_t key, size_t size, int shmflg)

-- 函数的作用:

  • 创建或获取共享内存的 id

-- 函数的参数:

  • key:键值
  • size:共享内存的大小,单位为字节

但是实际大小单位按页(1页 = 4KB)来算,按页向上取整
假设为5字节,则实际大小为4KB。
也就是小于1页是按1页算,大于1页按页向上取整,如1.5页就是2页,2.5页就是3页

  • shmflg:权限
    -- 固定值 IPC_CREAT | 0666 -- IPC_CREAT:如果共享内存不存在则创建,如果共享内存存在则获取

-- 函数的返回值:

  • 成功返回共享内存的 id
  • 失败返回-1

alt text

3、映射共享内存到进程的地址空间

-- 函数头文件

  • #include <sys/ipc.h>
  • #include <sys/shm.h>

-- 函数原型

  • void *shmat(int shmid, const void *shmaddr, int shmflg)

-- 函数的作用:

  • 将共享内存映射到进程的地址空间

-- 函数的参数:

  • shmid:共享内存的 id
  • shmaddr:映射的地址,一般传NULL,让系统自动分配
  • shmflg:权限

固定值 0

-- 函数的返回值:

  • 成功返回映射的地址
  • 失败返回-1

alt text

4、进行数据的写入和读取        

-- 如果传输的数据是字符串的格式的话,相当于对字符数组做操作,直接输入即可。

alt text

-- 如果传输的数据是结构体的话,需要使用memcpy函数

 -- memcpy

-- 我们映射成功之后,可以获取到共享内存的首地址,可以直接将他当作一个数组来操作
-- 当我们传输结构体时就不太方便,需要学习新的函数
-- “块”拷贝可以解决所有问题

  • 这个函数可以解决任何数据类型的数据传递问题

-- 函数头文件

  • #include <string.h>

-- 函数原型

  • void *memcpy(void *dest, const void *src, size_t n)

-- 函数的作用:

  • 将src指向的内存中的n个字节复制到dest指向的内存中(把一块内存的空间拷贝到另一个地址上去)

-- 函数的参数:

  • dest:目标地址
  • src:源地址
  • n:复制的字节数

-- 函数的返回值:

  • 返回目标地址(第一个参数的地址)

-- 使用该函数拷贝到共享内存中为数据的写入, 将数据从共享内存中拷贝出来为读取

alt text

5、对“块”进行赋值操作

-- 函数头文件

  • #include <string.h>

-- 函数原型

  • void *memset(void *s, int c, size_t n);

-- 函数的作用:对指定的内存块进行赋值操作

-- 函数的参数:

  • s:要赋值的内存块的首地址
  • c:要赋的值
  • n:要赋值的字节数

-- 函数的返回值:

  • 返回赋值后的内存块的首地址

-- 相当于给以p为首地址,总大小为4095字节的空间都赋值为0;

5、解除映射

-- 读取完数据后需要解除映射

-- 函数头文件

  • #include <sys/ipc.h>
  • #include <sys/shm.h>

-- 函数原型

  • int shmdt(const void *shmaddr)

-- 函数的作用:

  • 解除映射过来的共享内存

-- 函数的参数:

  • shmaddr:填写映射过来的共享内存地址

-- 函数的返回值:

  • 成功返回0
  • 失败返回-1

6、共享内存的多种操作函数

-- 函数头文件

  • #include <sys/ipc.h>
  • #include <sys/shm.h>

-- 函数原型

  • int shmctl(int shmid, int cmd, struct shmid_ds *buf)

-- 函数的作用:

  • 对共享内存进行多种操作         例如:获取共享内存信息 删除共享内存等

-- 函数的参数:

  • shmid:共享内存的 id
  • cmd:要进行的具体操作

IPC_RMID 删除共享内存 第三参数为 NULL
IPC_STAT 获取共享内存信息
IPC_SET 设置共享内存信息

  • buf:传出和传入的共享内存信息

-- 函数的返回值:

  • 成功返回0
  • 失败返回-1

-- 一般用来删除共享内存

-- shmctl(id,IPC_RMID,NULL);

-- 删除共享内存的指令

  • ipcrm -m shmid
  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值