进程间的通信共享内存

 共享内存概念介绍

         在Windows平台上,共享内存是一种进程间通信(IPC)机制,允许两个或多个进程共享一个公共内存区域,以便它们可以读取、写入或修改位于该内存区域中的数据。

        共享内存提供了一种快速且高效的数据交换方式,因为它允许进程直接访问同一块物理内存,而无需数据复制。        

        在Windows平台上,使用C++进行共享内存的通信可以通过WinAPI中的CreateFileMappingMapViewOfFile函数来实现。        

        使用UnmapViewOfFile函数来撤销映射的视图,使用CloseHandle函数来关闭文件映射对象的句柄。

  1. 文件映射对象(File Mapping)

    • 在Windows中,共享内存通常是通过文件映射对象实现的。一个文件映射对象可以基于一个实际的文件,或者是一个匿名的内存区域。
    • 使用CreateFileMapping函数创建文件映射对象,并指定其大小和名称。
  2. 内存映射文件(Memory-Mapped File)

    • 将文件内容或内存区域映射到进程的地址空间,使得文件内容或内存区域就像进程的普通内存一样可以被访问。
    • 使用MapViewOfFile函数将文件映射对象的视图映射到调用进程的地址空间。
  3. 视图(View)

    • 每个映射文件视图代表文件映射对象的一个特定部分,可以独立控制对这部分的访问权限和偏移量。
    • 一个文件映射对象可以有多个视图,每个视图可以被不同的进程或同一进程的不同线程所使用。
  4. 同步机制(Synchronization)

    • 由于多个进程可以同时访问共享内存,因此需要同步机制来避免竞态条件和数据不一致问题。
    • 可以使用互斥锁(Mutexes)、信号量(Semaphores)或临界区(Critical Sections)等同步机制来保护共享资源。
  5. 命名与匿名共享内存

    • 命名共享内存具有名称,可以通过文件系统进行访问,适用于不同进程间的通信。
    • 匿名共享内存没有名称,通常用于具有亲缘关系的进程间通信,如父子进程。
  6. 访问权限(Access Rights)

    • 创建文件映射对象时,可以指定不同的访问权限,如PAGE_READONLYPAGE_READWRITE等,以控制进程对共享内存的读写能力。
  7. 内存管理

    • 操作系统负责管理共享内存的生命周期,包括内存分配、保护和释放。
    • 使用UnmapViewOfFile函数来撤销映射的视图,使用CloseHandle函数来关闭文件映射对象的句柄。
  8. 性能考虑

    • 共享内存通常提供比基于消息或套接字的IPC机制更快的数据传输速度,因为它减少了数据复制的开销。
  9. 安全性

    • 需要考虑共享内存的安全性,确保只有授权的进程可以访问共享内存区域,防止潜在的安全隐患。

共享内存是一种强大的IPC机制,但它也需要谨慎使用,以确保数据的一致性和进程间的同步。在设计使用共享内存的应用程序时,开发者应该仔细考虑同步机制、错误处理和资源管理。

进程1创建内存映射:CreateFileMapping

#include <windows.h>
#include <iostream>
#include <string>

// 共享内存中的数据结构
struct SharedData {
    LONG counter; // 计数器
};


int main() {
    // 创建或打开一个文件映射对象
    HANDLE hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // 使用系统分页文件
        NULL,                    // 默认安全性
        PAGE_READWRITE,          // 读写权限
        0,                       // 最大对象大小(字节)
        sizeof(SharedData),      // 分配的初始大小
        L"MySharedMemory");      // 映射对象名称

    if (hMapFile == NULL) 
    {
        return 1;
    }

    // 映射文件视图到进程的地址空间
    SharedData* pData = static_cast<SharedData*>(MapViewOfFile(
        hMapFile,
        FILE_MAP_ALL_ACCESS, // 读写权限
        0,
        0,
        sizeof(SharedData)
    ));

    if (pData == NULL) {
        CloseHandle(hMapFile);
        return 1;
    }

    // 初始化共享数据
    pData->counter = 0;

    // 模拟数据操作
    for (int i = 0; i < 10; ++i) {
        pData->counter += i; // 修改共享数据
        std::cout << "Process 1: counter = " << pData->counter << std::endl;
        Sleep(500); // 等待半秒
    }

    // 完成数据操作后,取消映射
    if (!UnmapViewOfFile(pData)) {
        std::cerr << "UnmapViewOfFile failed (Error: " << GetLastError() << ")" << std::endl;
    }

    // 关闭文件映射对象句柄
    if (!CloseHandle(hMapFile)) {
        std::cerr << "CloseHandle failed (Error: " << GetLastError() << ")" << std::endl;
    }

    return 0;
}

进程二打开内存映射:OpenFileMapping

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值