【Windows进程通信】共享内存

共享内存主要是通过映射机制实现的。
  Windows 下进程的地址空间在逻辑上是相互隔离的,但在物理上却是重叠的。所谓的重叠是指同一块内存区域可能被多个进程同时使用。系统把同一块内存区域映射到了不同进程的地址空间中,从而达到共享内存的目的。
  示例代码中,一方是QT编写的程序来创建并读取共享内存的内容,另一方是VC程序修改共享内存中的内容:
  QT:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <iostream>
#include <Windows.h>
#include <windef.h>
using namespace std;
struct MapStruct
{
    char data[1024];
};
HANDLE hMap;
MapStruct* pBuffer;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    string strMapData("Hello world");
  // 创建一个命名的内存映射文件对象
   hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE,
                                    NULL,
                                    PAGE_READWRITE,
                                    0,
                                    sizeof (MapStruct),
                                    L"Test");
    // 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
   pBuffer = (MapStruct*)::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
   if(pBuffer)
       {
           memset(pBuffer, 0,  sizeof(pBuffer));
       }
       else
       {
           qDebug()<<"fail";
           CloseHandle(hMap);
           return;
       }
   strcpy(pBuffer->data,strMapData.c_str());
}


MainWindow::~MainWindow()
{
    // 解除文件映射,关闭内存映射文件对象句柄
    ::UnmapViewOfFile(pBuffer);
    ::CloseHandle(hMap);
    delete ui;
}

VC:

#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
struct MapStruct
{
    char data[1024];
};
int main()
{
    std::cout << "Hello ShareMemory!/n"<<std::endl;

    string strMapData("Hello world");
    HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"Test");
    if(NULL==hMap)
    { 
        std::cout << "No ShareMemory!/n" << std::endl;
    }
    else
    {
        MapStruct* myBuffer = (MapStruct*)::MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
        std::cout << myBuffer->data<<std::endl;
    }
}

下一步,添加一个线程来循环处理这个数据
QT:

void MyThread::run()
{
    while(threadRun)
    {
        sleep(1);
        std::cout << pBuffer->data<<std::endl;
    }
}

多个进程在这一处内存读写数据,肯定要通过同步互斥的手段来控制进程读取的顺序,避免同时对数据读写
这里采用内核事件,可以用于进程同步

QT:
   //创建一个事件
   bEventHandler=CreateEvent(NULL,FALSE,FALSE,L"myevent");

    while(threadRun)
    {
        //等待读取事件
        WaitForSingleObject(bEventHandler,INFINITE);
        std::cout << pBuffer->data<<std::endl;
    }
    
   VC:
    bEventHandler = OpenEvent(EVENT_ALL_ACCESS, FALSE, L"myevent");//获取事件句柄        
    MapStruct* myBuffer = (MapStruct*)::MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
    std::cout << myBuffer->data<<std::endl;
    memcpy(myBuffer->data,"1agag567",20);
    SetEvent(bEventHandler);//发送事件

QT程序启动后,创建共享内存,创建事件并等待事件到来。
VC启动后,打开共享内存,修改共享内存的内容,设置事件。
QT等到事件,打印共享内存中的内容。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值