实验四:进程间共享内存

实验四:进程间共享内存

1.实验目的:

通过实验了解windows如何通过内存映射文件机制来实现进程间共享内存;

2.实验内容

(1)创建一个写进程,创建一个命名的内存映射文件,将一个文件映射对象映射到当前应用程序的虚拟地址空间,在虚拟地址空间中写入数据;
(2)创建一个读进程,打开命名的内存映射文件,将文件映射对象映射到当前应用程序的虚拟地址空间,在虚拟地址空间中读出数据。

3.实验步骤:

程序一:写进程

实验描述:

(1) 利用CreateFileMapping()创建一个命名的内存映射文件对象;
(2) 利用MapViewOfFile()将文件映射到当前应用程序的虚拟地址空间;
(3)在虚拟地址空间中写入数据。

代码实现:
// 进程间共享内存写.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>

/*
  在A进程,我们通过 CreateFileMapping()函数来创建一个文件映射对象(使用 INVAILD_HANDLE_VALUE 来不指定文件句柄),
    然后调用MapFileOfView()函数来将文件映射对象映射到本进程中,
    利用copymemory来进行内存读写。

  在B进程,我们通过 OpenFileMapping()来打开,
    然后调用MapFileOfView()函数来将文件映射对象映射到本进程中,
    利用copymemory来进行内存读写。


*/


int main(int argc, char* argv[])
{
	HANDLE lhShareMemory;
	char* lpBuffer = NULL;

	//创建一个和物理文件无关的内存映射文件对象(换出时使用页文件)。
    /*
      HANDLE   CreateFileMapping(HANDLE   hFile,
                                 LPSECURITY_ATTRIBUTES   lpFileMappingAttributes,
                                 DWORD   flProtect,
                                 DWORD   dwMaximumSizeHigh,
                                 DWORD   dwMaximumSizeLow,
                                 LPCTSTR   lpName);
           hFile:指定欲在其中创建映射的一个文件句柄。
                 0xFFFFFFFF(-1,即INVALID_HANDLE_VALUE)表示换出时使用页文件。
           dwMaximumSizeHigh:文件映射的最大长度的高32位,
           dwMaximumSizeLow:文件映射的最大长度的低32位,
		   如果这两个参数都是零,就用磁盘文件的实际长度。
    */


    //CreateFileMapping()函数来创建一个文件映射对象(使用 INVAILD_HANDLE_VALUE 来不指定文件句柄)
	 lhShareMemory = CreateFileMapping(HANDLE(0xFFFFFFFF), NULL, PAGE_READWRITE,
	                                   0, 100, "mySharedMemory");

	 if (NULL == lhShareMemory)
	 {
	    if (ERROR_ALREADY_EXISTS == GetLastError())
		{
	       std:: cout << "Already exists!"<<std:: endl;
		}
	    else
		{
	       std::cout << "Create Sheared Memory unsuccessfully!"<< std::endl;
		}
	    return 0;
	 }

	 //把文件或文件的一部分映射到进程的虚拟地址空间。
     /*
       LPVOID   MapViewOfFile(HANDLE   hFileMappingObject,
                              DWORD   dwDesiredAccess,
                              DWORD   dwFileOffsetHigh,
                              DWORD   dwFileOffsetLow,
                              DWORD   dwNumberOfBytesToMap);
     */

     //MapFileOfView()函数来将文件映射对象映射到本进程中
	 lpBuffer = (char*)MapViewOfFile(lhShareMemory, FILE_MAP_WRITE, 0, 0, 100);
	 if (NULL == lpBuffer)
	 {
	    std::cout << "Get Share memory unsuccessfully!"<< std::endl;
	    return 0;
	 }


	 //写入数据
     strcpy(lpBuffer, "Hello,every students,please study hard! ");




	 std::cout << "进程通信:采用共享内存" << std::endl;
	 std::cout << "写进程" << std::endl;
	 std::cout << "写入数据:"<< std::endl<<lpBuffer << std::endl;

	 getchar();
	 //取消映射文件视图
	 UnmapViewOfFile(lpBuffer);

	 return 0;

}

程序二:读进程

实验描述:

(1) 利用OpenFileMapping()打开已创建的命名内存映射文件对象;
(2) 利用MapViewOfFile()将文件映射到当前应用程序的虚拟地址空间;
(3)从虚拟地址空间中读出数据。

代码描述:
// 进程间共享内存读.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include ".\..\实验三第三题\实验三虚拟内存的检测.cpp"

using namespace std;


int main(int argc, char* argv[])
{
	 HANDLE lhShareMemory;
	 char* lpcBuffer;

	 lhShareMemory = OpenFileMapping(FILE_MAP_READ, false, "mySharedMemory");


	// void WalkVM(HANDLE hProcess,char* pBlock)




	 if (NULL == lhShareMemory)
	 {
	    std::cout << "Open share memory unsuccessfully!" << std::endl;
	    DWORD ldwError = GetLastError();
	    std::cout << ldwError;
	    return 0;
	 }

	 //把文件或文件的一部分映射到进程的虚拟地址空间。
	 /*
       LPVOID   MapViewOfFile(HANDLE   hFileMappingObject,
                              DWORD   dwDesiredAccess,
                              DWORD   dwFileOffsetHigh,
                              DWORD   dwFileOffsetLow,
                              DWORD   dwNumberOfBytesToMap);
     */


	 lpcBuffer = (char*)MapViewOfFile(lhShareMemory, FILE_MAP_READ, 0, 0, 100);
	 if (NULL == lpcBuffer)
	 {
	    std::cout << "Open share memory unsuccessfully!";
	    return 0;
	 }
	 //std::cout << "::GetCurrentProcess()===>" <<hex<< lpcBuffer << std::endl;

	 printf("%x'\n'", lpcBuffer);

	 std::cout << "进程通信:采用共享内存" << std::endl;
	 std::cout << "读进程" << std::endl;
	 std::cout << "读入数据:" << std::endl;
	 for (int i = 0; i < 100; ++i)
	 {
	    std::cout << *(lpcBuffer + i);
	 }
	cout<<endl;

	::WalkVM(::GetCurrentProcess());

	 getchar();
	 UnmapViewOfFile(lpcBuffer);

	 return 0;

}


/*
思考题:
1.Windows下的进程间共享内存是利用什么机制实现的?
    内有的映射文件   映射

	基于共享存储区的共享存储器系统机制
	内存映射文件,把对文件的操作转变成对内存的操作


2.对于读写进程,物理内存是什么时候分配的?
    读写进程物理内存是写时分配的, 读时不重重新分配。

	首次使用的时候,对于写如数据时 strcpy(lpBuffer, "Hello,every students,please study hard! ");时候分配了物理内存,对于读进程不会分配。

3.读写进程之间的同步和互斥在共享内存机制中已经存在了,还是需要用户自己来实现?
    需要用户自己来实现
	共享内存并未提供进程同步和互斥机制,使用共享内存完成进程间通信时,需要借助互斥量或者信号量来完成进程的同步。

4.利用“虚拟内存的检测”程序检测读进程所映射的虚拟地址空间块的信息。

    //引入虚拟内存检测的文件
    #include ".\..\实验三第三题\实验三虚拟内存的检测.cpp"
	//当前所使用的的虚拟内存块(以16进制形式输出)
    printf("%x'\n'", lpcBuffer);
    //调用虚拟内存检测函数
	::WalkVM(::GetCurrentProcess());


  001d0000-001d1000 (4.00 KB) Committed, READONLY, Mapped
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr.史

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

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

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

打赏作者

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

抵扣说明:

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

余额充值