Linux 没有适用于windows的mremap?

Linux 没有适用于windows的mremap?,linux,windows,virtual-memory,Linux,Windows,Virtual Memory,据我所知,要在linux中保留一大块虚拟内存,可以使用MAP\u ANONYMOUS和MAP\u PRIVATE调用mmap,在windows上的等效系统调用是VirtualAlloc 然而,linux提供了mremap来调整内存映射的大小,手册页上说 更改虚拟地址和内存页之间的映射 我找不到windows的等效系统调用。似乎要重新分配内存,必须使用HeapAlloc而不是VirtualAlloc,然后使用HeapAlloc。关于HeapReAlloc,msdn表示 保存内存内容的过程涉及可能非

据我所知,要在linux中保留一大块虚拟内存,可以使用
MAP\u ANONYMOUS
MAP\u PRIVATE
调用
mmap
,在windows上的等效系统调用是
VirtualAlloc

然而,linux提供了
mremap
来调整内存映射的大小,手册页上说

更改虚拟地址和内存页之间的映射

我找不到windows的等效系统调用。似乎要重新分配内存,必须使用
HeapAlloc
而不是
VirtualAlloc
,然后使用
HeapAlloc
。关于HeapReAlloc,msdn表示

保存内存内容的过程涉及可能非常耗时的内存复制操作


那么,在Windows中是否没有重新映射虚拟内存片段的方法?如果没有,为什么不呢?

您可以使用地址窗口扩展(AWE)来实现。例如,您可以保留两个虚拟内存区域,然后将它们逐个映射到同一物理区域。也可以保留单个虚拟区域,但映射其中的不同部分

它不像Linux mremap那样方便,但它可以工作

签出地址窗口扩展(AWE)请:

我的工作代码基于MSDN示例供您参考。请记住,在运行Windows帐户之前,先在Windows中获取帐户的“锁定内存中的页面”权限

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#define MEMORY_REQUESTED 1024*1024 // request a megabyte

BOOL
LoggedSetLockPagesPrivilege(HANDLE hProcess,
    BOOL bEnable);

void _cdecl main()
{
    BOOL bResult;                   // generic Boolean value
    ULONG_PTR NumberOfPages;        // number of pages to request
    ULONG_PTR NumberOfPagesInitial; // initial number of pages requested
    ULONG_PTR *aPFNs;               // page info; holds opaque data
    PVOID lpMemReserved;            // AWE window
    PVOID lpMemReserved2;            // AWE window
    SYSTEM_INFO sSysInfo;           // useful system information
    int PFNArraySize;               // memory to request for PFN array

    GetSystemInfo(&sSysInfo);  // fill the system information structure

    _tprintf(_T("This computer has page size %d.\n"), sSysInfo.dwPageSize);

    // Calculate the number of pages of memory to request.

    NumberOfPages = MEMORY_REQUESTED / sSysInfo.dwPageSize;
    _tprintf(_T("Requesting %d pages of memory.\n"), NumberOfPages);

    // Calculate the size of the user PFN array.

    PFNArraySize = NumberOfPages * sizeof(ULONG_PTR);

    _tprintf(_T("Requesting a PFN array of %d bytes.\n"), PFNArraySize);

    aPFNs = (ULONG_PTR *)HeapAlloc(GetProcessHeap(), 0, PFNArraySize);

    if (aPFNs == NULL)
    {
        _tprintf(_T("Failed to allocate on heap.\n"));
        return;
    }

    // Enable the privilege.

    if (!LoggedSetLockPagesPrivilege(GetCurrentProcess(), TRUE))
    {
        return;
    }

    // Allocate the physical memory.

    NumberOfPagesInitial = NumberOfPages;
    bResult = AllocateUserPhysicalPages(GetCurrentProcess(),
        &NumberOfPages,
        aPFNs);

    if (bResult != TRUE)
    {
        _tprintf(_T("Cannot allocate physical pages (%u)\n"), GetLastError());
        return;
    }

    if (NumberOfPagesInitial != NumberOfPages)
    {
        _tprintf(_T("Allocated only %p pages.\n"), (void*)NumberOfPages);
        return;
    }

    // Reserve the virtual memory.

    lpMemReserved = VirtualAlloc(NULL,
        MEMORY_REQUESTED,
        MEM_RESERVE | MEM_PHYSICAL,
        PAGE_READWRITE);

    if (lpMemReserved == NULL)
    {
        _tprintf(_T("Cannot reserve memory.\n"));
        return;
    }

    lpMemReserved2 = VirtualAlloc(NULL,
        MEMORY_REQUESTED,
        MEM_RESERVE | MEM_PHYSICAL,
        PAGE_READWRITE);

    if (lpMemReserved2 == NULL)
    {
        _tprintf(_T("Cannot reserve memory.\n"));
        return;
    }

    // Map the physical memory into the window.

    bResult = MapUserPhysicalPages(lpMemReserved,
        NumberOfPages,
        aPFNs);

    if (bResult != TRUE)
    {
        _tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError());
        return;
    }
    else {
        int* pa = (int*)lpMemReserved;
        pa[1] = pa[100] = 0xF0F0;
        _tprintf(_T("MapUserPhysicalPages successfully at %p\n"), lpMemReserved);   
    }


    // unmap

    bResult = MapUserPhysicalPages(lpMemReserved,
        NumberOfPages,
        NULL);

    if (bResult != TRUE)
    {
        _tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError());
        return;
    }

    //remap
    bResult = MapUserPhysicalPages(lpMemReserved2,
        NumberOfPages,
        aPFNs);

    if (bResult != TRUE)
    {
        _tprintf(_T("Re-MapUserPhysicalPages failed (%u)\n"), GetLastError());
        return;
    }
    else {
        int* pa = (int*)lpMemReserved2;
        if(pa[1] != pa[100] || pa[100] != 0xF0F0)
            _tprintf(_T("Re-MapUserPhysicalPages failed (%u)\n"), GetLastError());
        _tprintf(_T("Re-MapUserPhysicalPages successfully at %p\n"), lpMemReserved2);
    }

    // Free the physical pages.

    bResult = FreeUserPhysicalPages(GetCurrentProcess(),
        &NumberOfPages,
        aPFNs);

    if (bResult != TRUE)
    {
        _tprintf(_T("Cannot free physical pages, error %u.\n"), GetLastError());
        return;
    }

    // Free virtual memory.

    bResult = VirtualFree(lpMemReserved,
        0,
        MEM_RELEASE);

    // Release the aPFNs array.

    bResult = HeapFree(GetProcessHeap(), 0, aPFNs);

    if (bResult != TRUE)
    {
        _tprintf(_T("Call to HeapFree has failed (%u)\n"), GetLastError());
    }

    _tprintf(_T("Successfully finished\n"));

}


/*****************************************************************
LoggedSetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.

Inputs:

HANDLE hProcess: Handle for the process for which the
privilege is needed

BOOL bEnable: Enable (TRUE) or disable?

Return value: TRUE indicates success, FALSE failure.

*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege(HANDLE hProcess,
    BOOL bEnable)
{
    struct {
        DWORD Count;
        LUID_AND_ATTRIBUTES Privilege[1];
    } Info;

    HANDLE Token;
    BOOL Result;

    // Open the token.

    Result = OpenProcessToken(hProcess,
        TOKEN_ADJUST_PRIVILEGES,
        &Token);

    if (Result != TRUE)
    {
        _tprintf(_T("Cannot open process token.\n"));
        return FALSE;
    }

    // Enable or disable?

    Info.Count = 1;
    if (bEnable)
    {
        Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
    }
    else
    {
        Info.Privilege[0].Attributes = 0;
    }

    // Get the LUID.

    Result = LookupPrivilegeValue(NULL,
        SE_LOCK_MEMORY_NAME,
        &(Info.Privilege[0].Luid));

    if (Result != TRUE)
    {
        _tprintf(_T("Cannot get privilege for %s.\n"), SE_LOCK_MEMORY_NAME);
        return FALSE;
    }

    // Adjust the privilege.

    Result = AdjustTokenPrivileges(Token, FALSE,
        (PTOKEN_PRIVILEGES)&Info,
        0, NULL, NULL);

    // Check the result.

    if (Result != TRUE)
    {
        _tprintf(_T("Cannot adjust token privileges (%u)\n"), GetLastError());
        return FALSE;
    }
    else
    {
        if (GetLastError() != ERROR_SUCCESS)
        {
            _tprintf(_T("Cannot enable the SE_LOCK_MEMORY_NAME privilege; "));
            _tprintf(_T("please check the local policy.\n"));
            return FALSE;
        }
    }

    CloseHandle(Token);

    return TRUE;
}
#包括
#包括
#包括
#定义所请求的内存1024*1024//请求一兆字节
布尔
LoggedSetLockPagesPrivilege(处理HPProcess,
布尔贝纳布尔);
void _cdeclmain()
{
BOOL-bResult;//通用布尔值
ULONG_PTR NumberOfPages;//要请求的页数
ULONG_PTR numberofpagesini;//请求的初始页数
ULONG_PTR*aPFNs;//页面信息;保存不透明数据
PVOID lpMemReserved;//AWE窗口
PVOID lpMemReserved2;//AWE窗口
SYSTEM\u INFO sSysInfo;//有用的系统信息
int PFNArraySize;//请求PFN数组的内存
GetSystemInfo(&sSysInfo);//填充系统信息结构
_tprintf(_T(“此计算机的页面大小为%d.\n”)、sSysInfo.dwPageSize);
//计算要请求的内存页数。
NumberOfPages=请求的内存/sSysInfo.dwPageSize;
_tprintf(_T(“请求%d页内存。\n”)、NumberOfPages);
//计算用户PFN阵列的大小。
PFNArraySize=页数*尺寸(ULONG_PTR);
_tprintf(_T(“请求%d字节的PFN数组。\n”)、PFNArraySize);
aPFNs=(ULONG_PTR*)HeapAlloc(GetProcessHeap(),0,PFNArraySize);
如果(aPFNs==NULL)
{
_tprintf(_T(“未能在堆上分配。\n”);
返回;
}
//启用特权。
如果(!LoggedSetLockPagesPrivilege(GetCurrentProcess(),TRUE))
{
返回;
}
//分配物理内存。
numberofpagesini=NumberOfPages;
bResult=AllocateUserPhysicalPages(GetCurrentProcess(),
&页数,
aPFNs);
if(bResult!=真)
{
_tprintf(_T(“无法分配物理页(%u)\n”)、GetLastError();
返回;
}
if(numberofpagesini!=NumberOfPages)
{
_tprintf(_T(“仅分配了%p页。\n”),(void*)NumberOfPages);
返回;
}
//保留虚拟内存。
lpMemReserved=VirtualAlloc(空,
请求的内存,
MEM_RESERVE | MEM_PHYSICAL,
页面(读写);
if(lpMemReserved==NULL)
{
_tprintf(_T(“无法保留内存。\n”));
返回;
}
lpMemReserved2=VirtualAlloc(空,
请求的内存,
MEM_RESERVE | MEM_PHYSICAL,
页面(读写);
if(lpMemReserved2==NULL)
{
_tprintf(_T(“无法保留内存。\n”));
返回;
}
//将物理内存映射到窗口中。
bResult=MapUserPhysicalPages(lpMemReserved,
页数,
aPFNs);
if(bResult!=真)
{
_tprintf(_T(“MapUserPhysicalPages失败(%u)\n”)、GetLastError();
返回;
}
否则{
int*pa=(int*)lpMemReserved;
pa[1]=pa[100]=0xF0F0;
_tprintf(_T(“MapUserPhysicalPages在%p\n成功”),lpMemReserved;
}
//取消映射
bResult=MapUserPhysicalPages(lpMemReserved,
页数,
无效);
if(bResult!=真)
{
_tprintf(_T(“MapUserPhysicalPages失败(%u)\n”)、GetLastError();
返回;
}
//重新映射
bResult=MapUserPhysicalPages(lpMemReserved2,
页数,
aPFNs);
if(bResult!=真)
{
_tprintf(_T(“Re-MapUserPhysicalPages failed(%u)\n”)、GetLastError();
返回;
}
否则{
int*pa=(int*)lpMemReserved2;
if(pa[1]!=pa[100]| | pa[100]!=0xF0F0)
_tprintf(_T(“Re-MapUserPhysicalPages failed(%u)\n”)、GetLastError();
_tprintf(_T(“在%p\n成功重新映射用户物理页面”),lpMemReserved2);
}
//释放物理页面。
bResult=FreeUserPhysicalPages(GetCurrentProcess(),
&页数,
aPFNs);
if(bResult!=真)
{
_tprintf(_T(“无法释放物理页,错误%u.\n”)、GetLastError();
返回;
}
//释放虚拟内存。
bResult=虚拟自由(LPMEMREFERED,
0,
内存释放);
//释放aPFNs阵列。
bResult=HeapFree(GetProcessHeap(),0,aPFNs);
if(bResult!=真)
{
_tprintf(_T(“对HeapFree的调用已失败(%u)\n”)、GetLastError();
}
_tprintf(_T(“成功完成”);
}
/*****************************************************************
LoggedSetLockPagesPrivilege:用于获取或
释放锁定物理页面的权限。
投入:
HANDLE hProcess:进程的句柄
特权是必需的
布尔·贝纳布尔: