1. 程式人生 > >windows核心編程之進程間共享數據

windows核心編程之進程間共享數據

font view oid 管道 section clas argc 例如 指向

有時候我們會遇到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核心編程之進程間共享數據