Windows中的共享内存的使用方法

在 Windows 操作系统中,共享内存是用于在多个进程之间共享数据的一种机制。你可以使用 Windows API 创建共享内存区域,从而在不同的进程之间传递数据。以下是实现共享内存的主要步骤:

1. 创建或打开一个文件映射对象

共享内存的核心是在内存中创建一个文件映射对象。使用 CreateFileMapping API 来创建或打开这个对象。

HANDLE hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE,   // 使用页面文件,而不是物理文件
    NULL,                   // 默认安全属性
    PAGE_READWRITE,         // 读写访问
    0,                      // 高位文件大小(0表示不指定大小)
    bufferSize,             // 低位文件大小,表示共享内存的大小
    L"Global\\MySharedMemory"); // 共享内存的名称

参数说明:

  • INVALID_HANDLE_VALUE 表示不使用实际文件,而是基于内存分页文件。
  • PAGE_READWRITE 表示该内存区域可读可写。
  • bufferSize 是共享内存的大小,单位为字节。
  • L"Global\\MySharedMemory" 是共享内存对象的名称,不同进程可以通过该名称访问同一共享内存。

2. 映射共享内存到当前进程的地址空间

通过 MapViewOfFile 函数,将文件映射对象映射到当前进程的地址空间,返回指向共享内存区域的指针。

LPVOID pBuf = MapViewOfFile(
    hMapFile,               // 共享内存对象的句柄
    FILE_MAP_ALL_ACCESS,    // 读写权限
    0,                      // 高位文件偏移
    0,                      // 低位文件偏移
    bufferSize);            // 映射的字节数

pBuf 是指向共享内存区域的指针,后续你可以使用它来读写共享内存中的数据。

3. 读写共享内存

你可以通过指向共享内存区域的指针 pBuf 来读写数据,例如:

// 写入数据
CopyMemory((PVOID)pBuf, someData, dataSize);

// 读取数据
CopyMemory(destinationBuffer, (PVOID)pBuf, dataSize);

4. 解除内存映射并关闭句柄

在使用完共享内存后,应该解除映射并关闭文件映射对象句柄。

UnmapViewOfFile(pBuf); // 解除映射
CloseHandle(hMapFile); // 关闭句柄

5. 访问共享内存的另一个进程

要访问已经创建的共享内存,另一个进程只需通过 OpenFileMapping 打开现有的文件映射对象:

HANDLE hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS,   // 读写权限
    FALSE,                 // 子进程继承句柄标志
    L"Global\\MySharedMemory"); // 同样的共享内存名称

打开后,和第一进程一样,通过 MapViewOfFile 将其映射到进程地址空间并进行数据操作。

实例

下面是一个使用共享内存的完整 C 语言实例,展示了两个进程之间如何通过共享内存传递数据。第一个进程创建共享内存并写入数据,第二个进程读取共享内存中的数据。

进程1:创建共享内存并写入数据

#include <windows.h>
#include <stdio.h>

int main() {
    // 共享内存大小
    const int bufferSize = 256;

    // 创建文件映射对象(共享内存)
    HANDLE hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // 使用页面文件
        NULL,                    // 默认安全属性
        PAGE_READWRITE,          // 读写访问
        0,                       // 高位文件大小
        bufferSize,              // 共享内存大小
        L"Global\\MySharedMemory"); // 共享内存的名称

    if (hMapFile == NULL) {
        printf("Could not create file mapping object (%d).\n", GetLastError());
        return 1;
    }

    // 将共享内存映射到进程地址空间
    LPCTSTR pBuf = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize);
    if (pBuf == NULL) {
        printf("Could not map view of file (%d).\n", GetLastError());
        CloseHandle(hMapFile);
        return 1;
    }

    // 写入数据到共享内存
    const char* message = "Hello from Process 1!";
    memcpy((PVOID)pBuf, message, (strlen(message) + 1) * sizeof(char));
    printf("Process 1: Written message to shared memory: %s\n", message);

    // 等待用户输入,保持进程不退出
    getchar();

    // 解除映射并关闭句柄
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);

    return 0;
}

进程2:读取共享内存中的数据

c复制代码#include <windows.h>
#include <stdio.h>

int main() {
    // 共享内存大小
    const int bufferSize = 256;

    // 打开已存在的文件映射对象(共享内存)
    HANDLE hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,  // 读写权限
        FALSE,                // 子进程不能继承句柄
        L"Global\\MySharedMemory"); // 共享内存的名称

    if (hMapFile == NULL) {
        printf("Could not open file mapping object (%d).\n", GetLastError());
        return 1;
    }

    // 将共享内存映射到进程地址空间
    LPCTSTR pBuf = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufferSize);
    if (pBuf == NULL) {
        printf("Could not map view of file (%d).\n", GetLastError());
        CloseHandle(hMapFile);
        return 1;
    }

    // 从共享内存中读取数据
    printf("Process 2: Read message from shared memory: %s\n", pBuf);

    // 解除映射并关闭句柄
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);

    return 0;
}

运行步骤:

  1. 先运行 进程1,它会创建共享内存并写入一条消息(Hello from Process 1!)。
  2. 运行 进程2,它会打开共享内存并读取进程1写入的消息。
  3. 你可以在进程1结束前(通过 getchar() 暂停)运行进程2,查看它读取到的共享内存内容。

关键点:

  • CreateFileMapping 用于创建共享内存。
  • MapViewOfFile 用于将共享内存映射到当前进程的地址空间。
  • OpenFileMapping 用于打开已存在的共享内存(在另一个进程中创建)。
  • 共享内存是通过名称 Global\\MySharedMemory 在多个进程之间共享的。

这两个程序可以展示如何通过共享内存在不同的进程之间传递数据。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值