Windows进程内存管理

以下内容摘抄自《Visual C++开发技术大全》,为学习笔记。

一、进程的创建

        进程的创建通过CreateProcess函数来实现, CreateProcess 函数通过创建一个新的进程以及在其地址空间内运行的主线程来启动并运行一个新的程序。具体在执行 CreateProcess 函数时,首先由操作系统负责创建一个进程内核对象,初始化计数为 1 ,并立即为新进程创建一块虚拟地址空间。随后将可执行文件或者其他任何必要的动态链接库文件的代码和数据装载到该地址空间中。在创建主线程时,也是首先由系统负责创建一个线程的内核对象,并初始化为1。最后启动主线程并执行进程的入口函数 WinMain,完成对进程和执行线程的创建。

        CreateProcess 函数用于创建一个新进程。语法如下:

BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);

参数说明:


本示例创建一个打开记事本的进程,并等待记事本程序的关闭才返回对程序的控制权,代码如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CreateProcessNotePad()  
  2. {  
  3.     WCHAR APPName[512];  
  4.     DWORD dwExitCode;  
  5.     PROCESS_INFORMATION pi;  
  6.     STARTUPINFO si = {sizeof(si)};  
  7.     GetWindowsDirectory(APPName, 512);  
  8.   
  9.     char buf[] = "\\NotePad.exe";  
  10.     int i = 0 ,j = 0;  
  11.     while (APPName[i] != 0)  
  12.     {  
  13.         i++;  
  14.     }  
  15.     while (j < sizeof(buf))  
  16.     {  
  17.         APPName[i++] = buf[j++];  
  18.     }  
  19.   
  20.     BOOL ret = CreateProcess(NULL, APPName, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);  
  21.     if (ret)  
  22.     {  
  23.         CloseHandle(pi.hThread);  
  24.         WaitForSingleObject(pi.hProcess, INFINITE);  
  25.         GetExitCodeProcess(pi.hProcess, &dwExitCode);  
  26.         CloseHandle(pi.hProcess);  
  27.     }  
  28. }  
二、虚拟内存空间

        在32位系统中,每个进程可以使用 4GB (2的32次方 Bytes)的地址空间。实际上,计算机中没有这些空间(空间是内存RAM空间),所以说系统系统使用的是虚拟内存空间。应用程序并不能访问所有的这4GB空间,在Windows NT 操作系统中,应用程序的进程只能访问这4GB空间的2GB,并且这4GB空间的最低和最高64KB也是不能访问的。

        虚拟内存的使用是Windows操作系统管理内存的一种方式。

三、进程间内存共享
       进程间内存共享主要是通过在虚拟内存中建立一块私有空间,来达到共享的目的。一个应用程序建立私有空间以后只有特定的程序才能访问这块空间,保证了数据的安全性。

       进程间内存共享主要用到CreateFileMappingMapViewOfFile和 OpenFileMapping三个函数,下面对这个3个函数进行介绍。

       (1)CreateFileMapping 在虚拟内存空间创建一个文件映射。

HANDLE WINAPI CreateFileMapping(
  _In_      HANDLE hFile,
  _In_opt_  LPSECURITY_ATTRIBUTES lpAttributes,
  _In_      DWORD flProtect,
  _In_      DWORD dwMaximumSizeHigh,
  _In_      DWORD dwMaximumSizeLow,
  _In_opt_  LPCTSTR lpName
);

函数成功返回内存映射文件句柄。失败返回 NULL。


使用完之后需要调用UnmapViewOfFile 函数释放资源。

Syntax

C++
BOOL WINAPI UnmapViewOfFile(
  _In_  LPCVOID lpBaseAddress
);

Parameters

lpBaseAddress [in]

A pointer to the base address of the mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFile or MapViewOfFileEx function.

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.


(2)MapViewOfFile。浏览由 CreateFileMapping 函数创建的文件映射。

LPVOID WINAPI MapViewOfFile(
  _In_  HANDLE hFileMappingObject,
  _In_  DWORD dwDesiredAccess,
  _In_  DWORD dwFileOffsetHigh,
  _In_  DWORD dwFileOffsetLow,
  _In_  SIZE_T dwNumberOfBytesToMap
);
返回值:成功返回映射文件的地址,失败返回 NULL 。


(3) OpenFileMapping 。打开由 CreateFileMapping 函数创建的文件映射。

HANDLE WINAPI OpenFileMapping(
  _In_  DWORD dwDesiredAccess,
  _In_  BOOL bInheritHandle,
  _In_  LPCTSTR lpName
);
返回值:成功返回该文件映射对象的句柄,失败返回 NULL。

注意:用完之后需要调用CloseHandle 关闭该句柄,释放资源。

三、示例。两个进程,第一个写入数据,第二个读出数据。

第一个进程代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #include <conio.h>  
  4. #include <tchar.h>  
  5.   
  6. #define BUF_SIZE 256  
  7. TCHAR szName[]=TEXT("Global\\MyFileMappingObject");  
  8. TCHAR szMsg[]=TEXT("Message from first process.");  
  9.   
  10. int _tmain()  
  11. {  
  12.    HANDLE hMapFile;  
  13.    LPCTSTR pBuf;  
  14.   
  15.    hMapFile = CreateFileMapping(  
  16.                  INVALID_HANDLE_VALUE,    // use paging file  
  17.                  NULL,                    // default security  
  18.                  PAGE_READWRITE,          // read/write access  
  19.                  0,                       // maximum object size (high-order DWORD)  
  20.                  BUF_SIZE,                // maximum object size (low-order DWORD)  
  21.                  szName);                 // name of mapping object  
  22.   
  23.    if (hMapFile == NULL)  
  24.    {  
  25.       _tprintf(TEXT("Could not create file mapping object (%d).\n"),  
  26.              GetLastError());  
  27.       return 1;  
  28.    }  
  29.    pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object  
  30.                         FILE_MAP_ALL_ACCESS, // read/write permission  
  31.                         0,  
  32.                         0,  
  33.                         BUF_SIZE);  
  34.   
  35.    if (pBuf == NULL)  
  36.    {  
  37.       _tprintf(TEXT("Could not map view of file (%d).\n"),  
  38.              GetLastError());  
  39.   
  40.        CloseHandle(hMapFile);  
  41.   
  42.       return 1;  
  43.    }  
  44.   
  45.   
  46.    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));  
  47.     _getch();  
  48.   
  49.    UnmapViewOfFile(pBuf);  
  50.   
  51.    CloseHandle(hMapFile);  
  52.   
  53.    return 0;  
  54. }  
第二个进程代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #include <conio.h>  
  4. #include <tchar.h>  
  5. #pragma comment(lib, "user32.lib")  
  6.   
  7. #define BUF_SIZE 256  
  8. TCHAR szName[]=TEXT("Global\\MyFileMappingObject");  
  9.   
  10. int _tmain()  
  11. {  
  12.    HANDLE hMapFile;  
  13.    LPCTSTR pBuf;  
  14.   
  15.    hMapFile = OpenFileMapping(  
  16.                    FILE_MAP_ALL_ACCESS,   // read/write access  
  17.                    FALSE,                 // do not inherit the name  
  18.                    szName);               // name of mapping object  
  19.   
  20.    if (hMapFile == NULL)  
  21.    {  
  22.       _tprintf(TEXT("Could not open file mapping object (%d).\n"),  
  23.              GetLastError());  
  24.       return 1;  
  25.    }  
  26.   
  27.    pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object  
  28.                FILE_MAP_ALL_ACCESS,  // read/write permission  
  29.                0,  
  30.                0,  
  31.                BUF_SIZE);  
  32.   
  33.    if (pBuf == NULL)  
  34.    {  
  35.       _tprintf(TEXT("Could not map view of file (%d).\n"),  
  36.              GetLastError());  
  37.   
  38.       CloseHandle(hMapFile);  
  39.   
  40.       return 1;  
  41.    }  
  42.   
  43.    MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);  
  44.   
  45.    UnmapViewOfFile(pBuf);  
  46.   
  47.    CloseHandle(hMapFile);  
  48.   
  49.    return 0;  
  50. }  

先运行第一个进程,再运行第二个进程。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值