1. 程式人生 > >Win3內存管理之私有內存跟共享內存的申請與釋放

Win3內存管理之私有內存跟共享內存的申請與釋放

入口 cati 種類 alt ber 物理 eof 註意 tex

      Win3內存管理之私有內存跟共享內存的申請與釋放

一丶內存簡介私有內存申請

  通過上一篇文章.我們理解了虛擬內存與物理內存的區別. 那麽我們有API事專門申請虛擬內存與物理內存的.

有私有內存跟共享內存. 私有內存的意思就是這塊內存申請只在本進程的物理頁當中. 共享內存就是這個物理頁 A B兩個進程都可以使用.

私有內存申請API

  VirtualAlloc / virtualAllocEx

LPVOID VirtualAlloc(  
LPVOID lpAddress, 你要申請的地址.可以指定地址.但是物理頁我們不知道那個地址是否存在.所以一般為0 SIZE_T dwSize, 申請內存的大小.一般為一個頁.雖然MSDN說了一Byte(字節) 為主. 但是我們知道物理內存是一個頁.所以申請一個頁即可. DWORD flAllocationType, 申請內存的類型. 是這樣的.我們申請內存在物理頁. 可以有兩種類型.一種類型就是物理內存直接申請.一種就是物理內存占位置.並不申請.一般用第一種. DWORD flProtect 內存的狀態.我們申請的內存狀態是可讀的 還是可寫的. 還是可讀寫的.

virtualAllocEx 是遠程內存申請.就是說我們可以通過指定的進程. 給這個指定進程申請內存.

new malloc的區別. 請註意.真正申請內存的其實是API. 而new malloc 是申請堆內存. 意思就是說. new malloc其實就是在已申請的內存上面劃分出來了一塊虛擬內存給你使用.

不管你使用沒使用. 而且new關鍵字本質也就是malloc 只不過可以進行構造. 而 malloc的底層是通過 HeapAlloc申請的. 並沒有進0環(內核)

二丶共享內存申請

1.共享內存申請

  共享內存其實就是物理頁可以共享使用了. A進程申請物理頁往這個物理頁填寫內容. B進程就可以讀取了.

我們具體的API

  1. 申請物理頁內存API

    

HANDLE CreateFileMapping(  HANDLE hFile,                       文件映射.申請的物理頁可以跟文件相映射.如果不需要文件只申請物理頁則不需要.
  LPSECURITY_ATTRIBUTES lpAttributes,                 SD安全屬性,每個內核對象都需要的安全屬性
  DWORD flProtect,                                    權限.你申請的這個物理頁是可讀的可寫的還是可讀寫.
  DWORD dwMaximumSizeHigh,                                     申請內存的高32位. windows為了支持64我操作系統.所以給了高低32位來保存地址. 如果是32位地址.則不需要.填0即可.
  DWORD dwMaximumSizeLow,                             低32位,你要申請的物理頁內存的大小
  LPCTSTR lpName                                     進程共享物理頁的名字.如果希望這個物理頁B進程可以使用則需要給一個名字.
返回值: 返回物理頁句柄索引.

有創建物理頁 也有打開物理頁 主要是B進程使用.

  

HANDLE OpenFileMapping(  DWORD dwDesiredAccess,  // access mode
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // object name);

當然如果B進程使用一樣可以使用CreateFileMaping. 只不過會返回文件對象已經存在的錯誤.

2.線性地址(虛擬地址) 關聯物理頁.

  上面申請了物理頁.那麽我們還需要將這個物理頁映射到線性地址.需要的API如下.

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // 物理頁句柄
  DWORD dwDesiredAccess,       // 線性地址訪問權限,註意跟物理頁最好一直.或者比物理頁更嚴格.
  DWORD dwFileOffsetHigh,      // 映射線性地址的偏移位置 高32位
  DWORD dwFileOffsetLow,       // 低32位
  SIZE_T dwNumberOfBytesToMap  // 內存映射結束位置;

3.取消關聯

BOOL UnmapViewOfFile(  LPCVOID lpBaseAddress   // starting address);  虛擬地址

關閉物理頁映射則使用CloseHandle. PS: 知識 引用計數-1. 為0了則會關閉.

具體代碼如下.

A進程B進程一樣. A進程寫入. B進程寫入.

  

// A.cpp : 定義控制臺應用程序的入口點。
//

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

int main()
{
    getchar();
    //A進程 申請物理頁
    HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, TEXT("共享內存"));


    //2.映射虛擬內存(線性地址的)
    LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0x1000);

    // A進程寫內存
    *(char *)lpBuf = a;  //寫內存
    printf("寫入內存為a \r\n");
    getchar();

    UnmapViewOfFile(lpBuf);
    CloseHandle(hMap);
    return 0;
}

技術分享圖片

B進程代碼:

  

// A.cpp : 定義控制臺應用程序的入口點。
//

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

int main()
{
    getchar();
    //A進程 申請物理頁
    HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, TEXT("共享內存"));


    //2.映射虛擬內存(線性地址的)
    LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0x1000);

    // A進程寫內存
    
    printf("讀取內存為 %c \r\n",*(char *)lpBuf);
    getchar();

    UnmapViewOfFile(lpBuf);
    CloseHandle(hMap);
    return 0;
}

這樣就實現了物理頁共享.

Win3內存管理之私有內存跟共享內存的申請與釋放