最近在做一个项目要在多个程序间传递数据,在网上调研了一番准备采用这种最简单的方式,总结记录一下。
在两个独立的进程之间如果想要互相通信,我们可以借助一个公共的媒介,例如开辟一个文件作为介质,一个进程往里写数据,另一个进程从中读数据,这样就实现了进程间数据通信,这种方法被称为“共享外存/共享文件”。本文介绍的的共享内存与其类似,只不过这个公共的介质变成了系统预留(reserve)的进程内的地址空间,有的地方又把这种“共享内存”的方式叫做“内存映射文件”方式。
主要使用的API函数有:
CreateFileMapping
MapViewOfFile
UnmapViewOfFile
CloseHandle
存储程序,这段代码通过命令行输入一个int数字,然后存储到共享的内存位置:
#include <iostream>
#include <Windows.h>
#include <tchar.h>
static HANDLE __shmem = INVALID_HANDLE_VALUE;
char* __shmbuf = NULL;
static const int SHM_SIZE = 1024;
using namespace std;
int main()
{
int a;
__shmem = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SHM_SIZE, _T("SHARE_MEMORY_ADDR"));
__shmbuf = (char *)MapViewOfFile(__shmem, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE);
while(1)
{
cin>>a;
*((int*)__shmbuf) = a;
}
UnmapViewOfFile(__shmbuf);
CloseHandle(__shmem);
__shmem = INVALID_HANDLE_VALUE;
__shmbuf = NULL;
}
读取程序,这段代码一直读取该段地址的数据,发现变化后打印出来:
#include <iostream>
#include <Windows.h>
#include <tchar.h>
static HANDLE __shmem = INVALID_HANDLE_VALUE;
char* __shmbuf = NULL;
static const int SHM_SIZE = 1024; // 共享内存的大小
using namespace std;
int main()
{
int LastData = 0;
__shmem = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SHM_SIZE, _T("SHARE_MEMORY_ADDR"));
__shmbuf = (char *)MapViewOfFile(__shmem, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE);
while(1)
{
if(LastData != *((int *)__shmbuf))
{
LastData = *((int *)__shmbuf);
printf("%d\n",LastData);
}
Sleep(100);
}
}
这里就简单测试一下,unmap和close函数就瞎搞了,实际使用的时候需要加上。(PS:如果使用Qt报错了,在pro里加上DEFINES-= UNICODE)
如图,右边的窗口是在一直从命令行读取数据然后存储,左边窗口显示数据的变化。
在实际使用中,可以使用结构体等数据类型,方便数据的操作。