window下进程通信之共享内存初探

一、内存存储的好处

1、两个进程之间进行数据交换,一般可以通过文件或者数据库。使用文件或者数据库作为存取介质的,一般是对运行效率可能没有太高的要求。对于结构稍微复杂的数据使用文件存储似乎不是一个太好的选择,结构化存储格式诸如xml或者json是可以满足需求的。但是需要多线程读取文件的时候又需要手动去实现控制线程之间的同步,而数据库正是一种解决了多线程并发读写数据的产品。但是这并不意味数据库一定比文件好用,这仍然取决于具体的应用场景。就好像如果只是一个人搬家可能只需要一辆小车子,可是如果是公司搬家可能就需要几辆大货车或者更多大货车了。选择合适的存储介质可以在很大程度上避免资源的浪费。哲人说存在就是合理的,也许确实如此。而且现在很多数据库产品也都有使用内存存储的实现,比如mysql数据库的memory引擎、oracle数据库中的TimesTen,还有VoltDB。它们都很好的利用了内存相较于磁盘的绝对读写优势。但是由于内存的易失性和不可持久化,在对数据安全较高的场景下是不适合作为存储的对象,使用分布式内存数据库存储是否能逐渐解决这种问题呢。

2、由于内存的特性,决定了它更适合作为中间数据交换的媒介。不管是进程内多线程对共享数据的访问还是进程之间进行数据交换,使用内存访问都是一种高效的方式。由于进程的隔离,使得一个进程不能直接访问另一个进程的内存,虽然不能直接访问,但是可以间接访问。操作系统作为应用程序的宿主,能够实现对应用程序无限制无阻碍的数据访问。两个进程的数据交换如果比喻成现实中的交易行为,那么操作系统扮演的就是中间商的角色了。进程A向操作系统申请共享的虚拟内存访问,操作系统向进程A返回内核对象凭证。进程B通过这个内核对象凭证实现对虚拟内存的访问。

二、共享内存读写实现

1、读取端

// SharedMemoryReader.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

int main()
{
    //获取高精度运算时间,微妙
    LARGE_INTEGER t1,t2,tc;
    QueryPerformanceFrequency(&tc);
    printf("Frequency: %u\n", tc.QuadPart);
    QueryPerformanceCounter(&t1);
    Sleep(1);
    QueryPerformanceCounter(&t2);
    printf("Begin   Time:   %u\n", t1.QuadPart);
    printf("End   Time:   %u\n", t2.QuadPart);
    printf("Lasting   Time:   %d\n", ((t2.QuadPart - t1.QuadPart) * 1000) / tc.QuadPart);
    printf("Lasting   Time:   %u\n", (t2.QuadPart - t1.QuadPart) * 1000);

    HANDLE hFileMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, NULL,"chenpingping");
    LPVOID pVoid = MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
    printf("hFileMapping=%d,pVoid=%s\n", hFileMapping,pVoid);
    CloseHandle(hFileMapping);
}

2、写入端

// SharedMemory.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

int main()
{
    DWORD dwMaximumSizeHigh = 0, dwMaximumSizeLow = 256;
    HANDLE hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, dwMaximumSizeHigh, dwMaximumSizeLow, "chenpingping");
    LPVOID pVoid = MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
    printf("hFileMapping=%d,pVoid=%d\n", hFileMapping, pVoid);
    memset(pVoid,0,dwMaximumSizeLow);
    BOOL bQuit = FALSE;
    char line[256];
    while(!bQuit){
        printf("type: ");
        char* str = fgets(line,256,stdin);
        *(str + strlen(str) - 1) = '\0';
        printf("you type【%s】\n",str);
        if(str && (strcmp(str,"quit")== 0 || strcmp(str,"QUIT")) == 0){
            bQuit = TRUE;
            break;
        }
        else{
            strcpy_s((char*)pVoid,strlen(str) + 1,str);
        }
    }
    printf("application exit");
    CloseHandle(hFileMapping);
    UnmapViewOfFile(pVoid);
}

写入端运行结果

 

读取端运行结果

 

注意在调用 CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, dwMaximumSizeHigh, dwMaximumSizeLow, "chenpingping") 时需要注意函数 CreateFileMappingA的第一个参数。如果传的是 INVALID_HANDLE_VALUE,这时候使用的虚拟内存页面,否则可能使用的是磁盘页面。

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天水麒麟姜伯约

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

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

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

打赏作者

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

抵扣说明:

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

余额充值