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

Windows和Linux内存共享机制

Windows和Linux内存共享机制

  • 引言
  • 1.Windows
    • 写操作
    • 读操作
  • 2.Linux
    • 写操作
    • 读操作
  • 3.Shell
      • 使用 tmux 运行 write 和 read
      • 说明


引言

在嵌入式开发领域,内存共享机制作为不同操作系统间实现高效数据交换的重要手段,尤其在对实时性和可靠性要求极高的环境中更为关键。近年来,随着ARINC 653标准的广泛应用,通过VxWorks仿真模拟器在Windows和Linux操作系统间建立内存共享机制已成为确保任务间稳定、同步运行的重要实现手段。本篇博客将深入探讨Windows和Linux各自的内存共享机制,结合ARINC 653标准在VxWorks中的实际应用,剖析其实现原理和实际使用中的关键技术,帮助读者更好地理解内存共享在跨平台环境中的应用场景与优势。

1.Windows

写操作


#include <windows.h>
#include <stdio.h>
#include <string.h>  // 用于字符串操作int main() {// 创建文件映射对象,大小为32字节HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,    // 使用系统分页文件NULL,                    // 默认安全性PAGE_READWRITE,          // 读写权限0,                       // 最大对象大小(高位)1024,                      // 最大对象大小(低位),32字节"Local\\MySharedMemory"   // 映射对象名称);if (hMapFile == NULL) {printf("Could not create file mapping object (%d).\n", GetLastError());return 1;}// 将文件映射到进程的地址空间LPVOID pBuf = MapViewOfFile(hMapFile,              // 文件映射对象句柄FILE_MAP_ALL_ACCESS,   // 读写权限0,                     // 偏移高位0,                     // 偏移低位32                     // 映射的字节数);if (pBuf == NULL) {printf("Could not map view of file (%d).\n", GetLastError());CloseHandle(hMapFile);return 1;}// 无限循环让用户输入数据并写入共享内存char input[32];while (1) {printf("Enter message to write to shared memory (up to 31 characters): ");fgets(input, sizeof(input), stdin);  // 从用户处读取输入input[strcspn(input, "\n")] = '\0';  // 移除换行符// 将用户输入的数据写入共享内存memcpy(pBuf, input, strlen(input) + 1);  // +1 是为了复制结束符printf("Data written to shared memory: %s\n", (char*)pBuf);}// 解除内存映射UnmapViewOfFile(pBuf);// 关闭文件映射对象句柄CloseHandle(hMapFile);return 0;
}

读操作


#include <windows.h>
#include <stdio.h>int main() {// 打开现有的文件映射对象HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,   // 访问权限FALSE,                 // 不继承句柄"Local\\MySharedMemory" // 映射对象名称);if (hMapFile == NULL) {printf("Could not open file mapping object (%d).\n", GetLastError());return 1;}// 映射文件视图到进程的地址空间LPVOID pBuf = MapViewOfFile(hMapFile,              // 文件映射对象句柄FILE_MAP_ALL_ACCESS,   // 读写权限0,                     // 偏移高位0,                     // 偏移低位32                     // 映射的字节数);if (pBuf == NULL) {printf("Could not map view of file (%d).\n", GetLastError());CloseHandle(hMapFile);return 1;}// 无限循环读取共享内存的数据while (1) {printf("Data read from shared memory: %s\n", (char*)pBuf);Sleep(1000);  // 每秒读取一次}// 解除内存映射UnmapViewOfFile(pBuf);// 关闭文件映射对象句柄CloseHandle(hMapFile);return 0;
}

2.Linux

写操作


#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>int main() {// 打开或创建共享内存对象int shm_fd = shm_open("/my_shared_memory", O_CREAT | O_RDWR, 0666);if (shm_fd == -1) {perror("shm_open");return 1;}// 配置共享内存大小ftruncate(shm_fd, 1024);  // 设置大小为1024字节// 映射共享内存到进程地址空间void* ptr = mmap(0, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);if (ptr == MAP_FAILED) {perror("mmap");return 1;}// 无限循环让用户输入数据并写入共享内存char input[1024];while (1) {printf("Enter message to write to shared memory: ");fgets(input, sizeof(input), stdin);  // 从用户处读取输入input[strcspn(input, "\n")] = '\0';  // 移除换行符// 将用户输入的数据写入共享内存memcpy(ptr, input, strlen(input) + 1);  // +1 是为了复制结束符printf("Data written to shared memory: %s\n", (char*)ptr);}// 解除内存映射munmap(ptr, 1024);// 关闭共享内存对象close(shm_fd);shm_unlink("/my_shared_memory");return 0;
}

读操作


#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>int main() {// 打开现有的共享内存对象int shm_fd = shm_open("/my_shared_memory", O_RDONLY, 0666);if (shm_fd == -1) {perror("shm_open");return 1;}// 映射共享内存到进程地址空间void* ptr = mmap(0, 1024, PROT_READ, MAP_SHARED, shm_fd, 0);if (ptr == MAP_FAILED) {perror("mmap");return 1;}// 无限循环读取共享内存的数据while (1) {printf("Data read from shared memory: %s\n", (char*)ptr);// sleep(1);  // 每秒读取一次}// 解除内存映射munmap(ptr, 1024);// 关闭共享内存对象close(shm_fd);return 0;
}

3.Shell

这里的shell由于要开两个终端所以不能使用SSH会话或者处于不能使用图形化界面的终端

#!/bin/bash# 编译 read.c 和 write.c
gcc - o write write.c - lrt   #  - lrt 是在一些系统上链接实时库所需的
gcc - o read read.c - lrt# 检查编译是否成功
if [[ !- f "write" || !- f "read" ]]; then
echo "Compilation failed!"
exit 1
fi# 在新终端中运行 write 程序
gnome - terminal -- bash - c "./write; exec bash" &# 在新终端中运行 read 程序
gnome - terminal -- bash - c "./read; exec bash" &# 等待所有后台进程结束
wait

如果只是在命令行界面下运行程序,可以使用 screentmux 工具来在多个会话中运行 writeread 程序。这里是如何做到这一点的。

使用 tmux 运行 write 和 read

  1. 安装 tmux(如果尚未安装):

    sudo apt install tmux  # Debian/Ubuntu 系统
    sudo yum install tmux  # CentOS/RHEL 系统
    
  2. 创建新的 Memory_Sharing.sh 脚本
    修改 Memory_Sharing.sh 脚本以使用 tmux

    #!/bin/bash# 编译 read.c 和 write.c
    gcc -o write write.c -lrt   # -lrt 是在一些系统上链接实时库所需的
    gcc -o read read.c -lrt# 检查编译是否成功
    if [[ ! -f "write" || ! -f "read" ]]; thenecho "Compilation failed!"exit 1
    fi# 创建一个新的 tmux 会话,命名为 "memory_sharing"
    tmux new-session -d -s memory_sharing# 在第一个窗格中运行 write 程序
    tmux send-keys -t memory_sharing './write' C-m# 在新窗格中运行 read 程序
    tmux split-window -h
    tmux send-keys -t memory_sharing './read' C-m# 附加到 tmux 会话
    tmux attach-session -t memory_sharing
    

说明

  1. 创建 tmux 会话

    • tmux new-session -d -s memory_sharing 创建一个新的后台会话。
  2. 在窗格中运行程序

    • tmux send-keys -t memory_sharing './write' C-m 在第一个窗格中运行 write 程序。
    • tmux split-window -h 创建一个新的窗格,并在其中运行 read 程序。
  3. 附加到会话

    • tmux attach-session -t memory_sharing 附加到创建的 tmux 会话,可以看到两个程序的输出。

运行该脚本后,将在 tmux 中看到 writeread 程序的输出。按 Ctrl + b 然后按 c 可以创建新的窗格,按 Ctrl + b 然后按 o 切换窗格,按 Ctrl + b 然后按 d 可以分离会话。

http://www.lryc.cn/news/474373.html

相关文章:

  • windows@命令行中获取环境变量取值不展开取值(原值)
  • 如何找到多平台内容爆款进行批量复刻?
  • 【UML】- 用例图(结合银行案例解释其中的奥义)
  • 浅谈UI自动化
  • 三、k8s快速入门之Kubectl 命令基础操作
  • 深度学习-BP算法详解
  • Java审计对比工具JaVers使用
  • unity中预制体的移动-旋转-放缩
  • 【压力测试】如何确定系统最大并发用户数?
  • ubuntu常用基本指令简记
  • 【解决方案】用git reset --hard重置了提交但是发现reset了一些本不该reset的内容,是不是寄了?
  • ACM模式下Java读取控制台输入注意事项及输出规范化
  • 面试题整理 2
  • 华为自研仓颉编程语言官网上线 首个公测版本开放下载
  • NVR监测软件/设备EasyNVR多品牌NVR管理工具/设备对城市安全有哪些具体益处?
  • MFC工控项目实例二十八模拟量信号每秒采集100次
  • 安装scrcpy-client模块av模块异常,环境问题解决方案
  • 硅谷甄选(11)角色管理
  • C语言结构体 变量对齐原理
  • 【oracle】正则表达式
  • 如何找到网上爆款内容,快速复制扩大品牌声量
  • 补齐:相交链表:扣160
  • Java项目实战II基于Java+Spring Boot+MySQL的智能推荐的卫生健康系统(开发文档+数据库+源码)
  • NET Core的AOP实施方法1 DispatchProxy
  • AIGC生成式人工智能——泼天的富贵(三)
  • GetX的一些高级API
  • 【笔面试常见题:三门问题】用条件概率、全概率和贝叶斯推导
  • 刘艳兵-DBA011-应用使用Oracle数据库,必须启动哪些服务?
  • 注释多行代码的vim插件
  • Docker 安装HomeAssistant智能家居系统