Windows和Linux下共享内存使用

2023-10-26

源码地址: https://github.com/ylmbtm/GameProject3

      看过我开源代码的朋友知道,我这个项目在逻辑服和数据服进行数据同步采用的就是共享内存。其实数据同步的方式有很多种,其中使用较多的一种方式就是tcp网络协议同步,不过这种方式我觉得编码过程略嫌繁琐,使用也不够方便,开发效率不如共享内存。

      当然也有不少朋友吐槽共享内存,说共享内存没法跨机器分布式部署,说实话这个要看你的需求,只有根据项目需求制定的合适方案,以我工作这些年经验看,一般的手游项目远远够用了,共享内存除了开发方便还有几个优点,一是传输效率高,二是节约内存,三是服务器挂了之后能快速恢复。

      有好多的朋友不太了解,什么是共享内存,我这篇文章就来讲讲共享内存的一些基本知识和共享内存在windows和linux使用的一些异同点。

      共享内存是进程间同步数据的一种方式,它允许多个进程访问同一块物理内存,就是一段物理内存被同时映射到不同进程地址空间中,当一个进程修改这块内存的值,其它进程就可以直接读取到值的改变。

      对共享内存的操作实际上就五个关键操作:创建、打开、映射、释放、关闭或者删除, 这五个操作在windows和linux下是不一样的,我们先业看windows下的操作方法:

Windows版本:

1.创建共享内存

HANDLE CreateFileMapping(
    HANDLE hFile,
    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
    DWORD flProtect,
    DWORD dwMaximumSizeHigh,
    DWORD dwMaximumSizeLow,
    LPCWSTR lpName
    );

说明:

hFile: 这里是文件句柄,如果传实际的文件句柄就和linux 下的mmp文件映射类似的功能了,我们这里仅仅使用共享内存功能,赋值  INVALID_HANDLE_VALUE(0xFFFFFFFF)就可以了。

dwMaximumSizeLow: 创建的共享内存的大小。

lpName: 这个可以理解为这块共享内存的唯一标识,便于多个进程能访问到同一块共享内存。

2.打开共享内存

HANDLE OpenFileMapping(
    DWORD dwDesiredAccess,
    BOOL bInheritHandle,
    LPCWSTR lpName
    );

说明:

dwDesiredAccess: 需的访问权限,FILE_MAP_READ | FILE_MAP_WRITE表示同时需要读和写权限。

lpName:共享内存的唯一标识。

3.映射共享内存到进程空间

LPVOID MapViewOfFile(
    HANDLE hFileMappingObject,
    DWORD dwDesiredAccess,
    DWORD dwFileOffsetHigh,
    DWORD dwFileOffsetLow,
    SIZE_T dwNumberOfBytesToMap
    );

说明:

hFileMappingObject:共享内存句柄,就是上两个方法的返回值。

dwDesiredAccess:需的访问权限,FILE_MAP_READ | FILE_MAP_WRITE表示同时需要读和写权限。

返回值: 共享内存映射到本地进程的地址。

4.释放共享内存

BOOL UnmapViewOfFile(
    LPCVOID lpBaseAddress
);

说明:

lpBaseAddress:共享内存印射到本地进程的地址,也是上一个方法的返回值。

5.关闭共享内存

BOOL CloseHandle(
    HANDLE hObject
);

说明:

hObject:共享内存的句柄。

Linux:

1. 创建共享内存

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

key: 共享内存的key, 唯一标识这块共享内存。

size: 共享内存的大小 。

shmflg: 用于创建共享内存时可填值: 0666 | IPC_CREAT | IPC_EXCL

2. 打开共享内存

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

key: 共享内存的id, 唯一标识这块共享内存。

size: 共享内存的大小 ,用于打开共享内存时,可填0。

shmflg: 用于打开共享内存时,可填0。

3.映射共享内存到进程空间

void *shmat(int shm_id, const void *shm_addr, int shmflg);

shm_id:是由shmget()函数返回的共享内存标识。

shm_addr:指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

shm_flg:是一组标志位,通常为0。

4.释放共享内存

int shmdt(const void *shmaddr);

shmaddr:是shmat()函数返回的地址指针,调用成功时返回0,失败时返回-1.

5.删除共享内存

int shmctl(int shm_id, int command, struct shmid_ds *buf);

shm_id:是由shmget()函数返回的共享内存标识。

command:命令 IPC_RMID表示删除共享内存, 但实际上并不是真的从内核删除一个段,而是仅仅把这个段标记为删除,实际的删除发生在这块共享内存nattch为0时。

在linux下还有命令用来管理共享内存

1.查看系统中的所有的共享内存

ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x01010000 147226624  root       666        73728      2                       
0x01020000 147259393  root       666        1687552    2                       
0x01030000 147292162  root       666        114688     2                       
0x01040000 147324931  root       666        98304      2                       
0x01050000 147357700  root       666        73728      2                       
0x01060000 147390469  root       666        2785280    2                       
0x01070000 147423238  root       666        360448     2                       
0x01080000 147456007  root       666        90112      2   

2.删除系统中的共享内存

ipcrm -m [shmid]

说明: shmid为共享内存的id

2.查看系统中全部共享内存的统计

ipcs -m -u

在linux下还可自己修改共享内存的内核配置:

#vi /etc/sysctl.conf
kernel.shmmax=15461882265
kernel.shmmin=3774873
kernel.shmall=3774873

shmmax : 配置了单个共享内存段的最大值

shmmin : 配置了单个共享内存段的最小值

shmall: 可用共享内存的总数量(页面)

需要注意的是, 在Window和Linux下共享内存的表现不一样,在Window下,只要关联共享内存的进程全部退出,即便没有正确的释放关闭,操作系统也会全部释放关闭,而在linux下 ,只有关联共享的内存的进程,有一个没有正确的释放关闭,那么这块共享内存就会一直存在,需要手动用ipcrm来删除。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows和Linux下共享内存使用 的相关文章

随机推荐

  • 0-1背包问题

    题目描述 有n件物品和一个容量为v的背包 第i件物品的重量是w i 价值是p i 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量 且价值和最大 算法分析 动态规划的题目一直是比较有难度 这种题目炸看往往连个思路都没有 往往需要数
  • expect 使用实例

    自动登录一台 服务器 代码 root localhost D151SP160 cat test1 exp bin expect set timeout 2 set user name lindex argv 0 set mypassword
  • Delphi转Java开发的辛酸

    工作已经快两年了 回想起以前的选择 真是让人不是滋味啊 通过近段时间的仔细思考和对自己以后职业规划 现在越来越想往JAVAWEB方向发展 想了许久 我还是决定辞职 放弃现在这份安逸的工作 易然的选择做JAVA这边道路 今天刚刚出来面试 就让
  • 数据结构-哈希-哈希表实现

    哈希表实现 一 哈希概念 哈希概念 常见哈希函数 哈希冲突 哈希冲突的解决 二 闭散列实现 闭散列的结构 插入 查找 删除 闭散列总结 三 哈希桶实现 哈希桶的结构 插入 查找 删除 析构 拷贝构造 赋值运算符重载 四 哈希表总结 开散列与
  • 安装windows版caffe

    MATLAB操作caffe框架 安装之前先谈谈我的电脑硬件配置 Qudra K600 的GPU 计算能力是3 0 你在安装之前也要搞清楚自己的GPU显卡是什么 看看到底支持不支持CUDA 如果支持 要查查计算能力是多少 后面配置参数要用到
  • windows环境下查看Python的安装路径

    1 windows r 进入cmd命令 2 查看python安装路径 where python
  • 常见的几种Sort排序算法

    几种常见的Sort排序算法 1 排序的基本概念 有n个记录的序列 其相应关键字的序列是 相应的下表序列是 通过排序 要求找出当前下标序列的一种排列 使得相应的关键字满足如下的非递减 或非递增 关系 这样就得到一个按关键字有序的记录序列 该文
  • ant design pro 跳转新页面 修改功能

    ant design pro 修改功能跳转新页面 背景 例子 页面跳转 背景 在官方提供的例子中 是以弹窗的形式做的修改和新增 在项目中如果遇到 采集项数较多 会在修改页面添加别的功能的情况下 弹窗满足不了此需求了 例子 页面跳转 先说修改
  • 计算机网络校园网网络设计报告,计算机网络课程设计报告-校园网的组建和应用...

    计算机网络课程设计报告 校园网的组建和应用 北 京 邮 电 大 学校园网的组建和应用 计算机网络课程设计指导老师 吴建伟老师刘亦桐老师小组成员 姓名 班级 学号王 超 06121 060648曹 振 06121 060643郭 嵩 0612
  • 我的创作纪念日

    机缘 咱记性不好 技术也差 实验过程中总是遇到奇奇怪怪的问题 有些问题找了好久也没找到完全适合自己情况的解决方案 很多情况下需要结合多篇文章进行总结 为了下次遇到类似问题能够快速解决 同时也为遇到同样问题的小伙伴们能够快速找到详细的问题解决
  • 基于HAL库的stm32f103c8t6的快速开发笔记(简易版)—— 5、STM32的PWM输出(附舵机控制)

    1 概念了解 首先了解到 PWM生成是在通用定时器的基础上配置的 每个通用定时器都有多路通道输出PWM信号 这里以TIM4 定时器4 为例 在图形配置面板找到TIM4的通道一作为PWM输出管脚 其管脚为PB6 打开左侧定时器配置面板 可以看
  • HBase工作机制

    1 图示 2 组件说明 Client hbase客户端 1 包含访问hbase的接口 比如 linux shell java api 2 除此之外 它会维护缓存来加速访问hbase的速度 比如region的位置信息 Zookeeper 1
  • 【MySQL】基础SQL语句——库的操作

    文章目录 一 创建数据库 1 1 基础语句 1 2 字符集和校验规则 1 3 校验规则对读取数据的影响 二 查看数据库 三 修改数据库 四 删除数据库及备份 4 1 删除 4 2 备份和还原 结束语 一 创建数据库 1 1 基础语句 最简洁
  • 微信小程序期末大作业 点餐小程序

    点餐小程序 小程序如图所示 下载链接在文末 点我下载资源 https download csdn net download weixin 43474701 58000564
  • xshell连接ubuntu失败排错指南

    本人在学习linux系统中出现了一些远程连接失败的问题 以此笔记记录下排错过程 注意 VMware桥接模式需要让虚拟机的ip和物理机的ip在同一网段 因此需要手动配置linux系统网卡 NAT模式虚拟机ip不需要和物理机ip在同一个网段 但
  • Python Tkinter详解 (二)Label标签的使用

    一个简单到不能再简单的标签 import tkinter as tk window tk Tk window title Label的使用 window geometry 400x400 label tk Label window text
  • 【动手学深度学习v2】第二章预备知识-2.1入门

    入门 深度学习领域方向自然语言处理 计算机视觉 深度学习 具体领域 图片分类 物体检测与分割 样式迁移 为图片加滤镜 人脸合成 文字生成图片 文字生成 无人驾驶 张量 表示一个多维矩阵 核心是一个数据容器 多数情况下包含数字 可以想象成一个
  • Java中WebService接口的生成、打包成.exe、设置成Windows服务、及其调用、Apache CXF调用

    一 Java中WebService接口的生成 1 在eclipse工具中新建一个普通的JAVA项目 新建一个java类 JwsServiceHello java package com accord ws import javax jws
  • 蓝桥杯2014年第五届真题-拼接平方数

    题目 题目链接 题解 实现题 题目大意 将一个区间内的数拆成两个数后 若原数 拆得的第一个数和拆得的第一个数均为平方数则输出 直接遍历区间内所有的数可能会超时 因此我们直接取区间内的平方数 只遍历区间内的平方数 时间复杂度会降很多 对于每个
  • Windows和Linux下共享内存使用

    源码地址 https github com ylmbtm GameProject3 看过我开源代码的朋友知道 我这个项目在逻辑服和数据服进行数据同步采用的就是共享内存 其实数据同步的方式有很多种 其中使用较多的一种方式就是tcp网络协议同步