windows核心编程之进程间共享数据

Posted lytwajue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows核心编程之进程间共享数据相关的知识,希望对你有一定的参考价值。

  有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例。

我们能够在程序中定义一个全局变量。初始化为0。每当程序启动后就加1。当然我们我们能够借助第三方介质来储存这个变量,然后解析。

这样做必须做到先写入后解析。不能实时更新数据。假设不考虑其它储存介质。仅仅是进程中的通信,应该怎么做呢?windows提供了一些可行的方法,以下介绍经常使用的两种。

一、共享数据段

#include "stdafx.h"
#include <Windows.h>

};

#pragma data_seg("Shared")
volatile int g_lAppInstances = 0 ;
#pragma data_seg()

#pragma comment(linker, "/Section:Shared,RWS")

int _tmain(int argc, _TCHAR* argv[])
{
	printf("the instance of app is %d\n", ++g_lAppInstances) ;
	getchar() ;
	return 0;
}

以上就是在代码中增加共享数据段。当执行一个程序的实例的同一时候打开还有一个实例。g_lAppInstances会指向同一个内存,这样就能够做到数据共享。可是这样的方法的缺点是仅仅能共享一个变量的数据,对于结构体是不行的。


二、内存映射

第一个程序:

#include "stdafx.h"
#include <Windows.h>

struct SharedData{
	int a ;
	int b;
	float c ;
	SharedData(int x, int y, float z){
		a = x ;
		b = y ;
		c = z ;
	}
};

const int BUF_SIZE = 256 ;
TCHAR szName[] = _T("Global\\MyFileMappingObj") ;

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
		NULL, PAGE_READWRITE, 0, BUF_SIZE, szName) ;
	if(hMapFile == NULL){
		_tprintf(_T("Could not create file mapping obj\n")) ;
		return 1 ;
	}

	LPCTSTR pBuf = (LPCTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE) ;
	if(pBuf == NULL){
		_tprintf(_T("could not mapping file\n")) ;
		CloseHandle(hMapFile) ;	
		return 2 ;
	}
	<span style="white-space:pre">	</span><pre name="code" class="cpp"><span style="white-space:pre">	</span>SharedData *pSd = (SharedData*)pBuf ;
	_tprintf(_T("the data from IPC2 is %d, %d, %f\n"), pSd->a, pSd->b, pSd->c) ;
	getchar() ;
UnmapViewOfFile(pBuf) ;CloseHandle(hMapFile) ;return 0;}


第二个程序:

#include "stdafx.h"
#include <Windows.h>

struct SharedData{
	int a ;
	int b;
	float c ;
	SharedData(int x, int y, float z){
		a = x ;
		b = y ;
		c = z ;
	}
};

const int BUF_SIZE = 256 ;
TCHAR szName[] = _T("Global\\MyFileMappingObj") ;

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
		NULL, PAGE_READWRITE, 0, BUF_SIZE, szName) ;
	if(hMapFile == NULL){
		_tprintf(_T("Could not create file mapping obj\n")) ;
		return 1 ;
	}

	LPCTSTR pBuf = (LPCTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE) ;
	if(pBuf == NULL){
		_tprintf(_T("could not mapping file\n")) ;
		CloseHandle(hMapFile) ;	
		return 2 ;
	}
	
	<pre name="code" class="cpp"><span style="white-space:pre">	</span>TCHAR s[BUF_SIZE] ;
	SharedData sd(1, 2, 3.14) ;
	memcpy((LPVOID)pBuf, &sd, sizeof(sd)) ;
UnmapViewOfFile(pBuf) ;CloseHandle(hMapFile) ;return 0;}


我们先执行第二个程序,然后再执行第一个程序,发现第一个程序打印出了第二个程序一个结构体的值,达到了数据共享的目的。

进程间的通信还包含剪切板,邮槽。管道等,可是他们本质上都是利用的内存映射文件实现的。

以上是关于windows核心编程之进程间共享数据的主要内容,如果未能解决你的问题,请参考以下文章

多线程编程

Linux环境编程之共享内存区:共享内存区简单介绍

linux进程间通信之System V共享内存详解及代码示例

Windows进程间通信

Qt进程间通信之QSharedMemory示例

Qt进程间通信之QSharedMemory示例