背景:我正在尝试创建一个可由多个进程访问的内存映射文件。在下面的代码中,我只输入了与我目前必须使事情更简单的问题有关的代码。根据msdn,我应该能够创建一个文件映射,映射文件的视图并关闭我从 CreateFileMapping 接收到的句柄,而 MapViewOfFile 将使我的 FileMap 保持活动状态。FileMap 应该仍然可以访问,直到我 UnmapViewOfFile。
MSDN: CreateFileMapping 函数
文件映射对象的映射视图维护对对象的内部引用,并且文件映射对象在对它的所有引用都被释放之前不会关闭。因此,要完全关闭文件映射对象,应用程序必须通过调用 UnmapViewOfFile 取消映射文件映射对象的所有映射视图,并通过调用 CloseHandle 关闭文件映射对象句柄。这些函数可以按任何顺序调用。
问题:成功映射文件视图并关闭 CreateFileMapping 接收到的句柄后,FileMap 不再存在(它应该仍然存在)并且我的 MemMapFileReader 能够创建一个错误为 0 的新映射。(当它应该接收错误 183 '已经存在')
错误的解决方案:不关闭句柄允许它被 MemMapFileReader 程序访问,但会导致 MemMapFileCreator 中的句柄泄漏,因为在进程关闭之前句柄永远不会关闭。
问题:我错过了什么或做错了什么?
内存映射文件创建器
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
TCHAR szMsg[] = TEXT("Message from first process.");
int _tmain()
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, …Run Code Online (Sandbox Code Playgroud) 我有一个Windows应用程序运行而不需要提升.我需要为应用程序的所有正在运行的实例之间共享的内存数组创建一个文件映射对象(请注意,其中一些实例可能在不同的登录会话中运行.)
我调用CreateFileMapping API来创建它,使用全局名称,即Global\sharedname使用安全描述符提供all访问权限,everyone但API失败,错误代码为5,或者ERROR_ACCESS_DENIED.
然后我开始阅读文档,发现我的进程需要SeCreateGlobalPrivilege特权.但是当我尝试分配该权限时,AdjustTokenPrivileges返回错误代码ERROR_NOT_ALL_ASSIGNED,我被卡住....
那么这里有什么诀窍,那个疯狂的MS怎么想让我们这样做?
PS.我之前可以使用相同的all access for everyone安全描述符和Global\sharedmutex名称创建一个全局命名的互斥锁(用于对共享内存的同步访问),而不会出现问题.
我想在 Windows 上调整内存映射文件的大小,而不会使从先前调用MapViewOfFileEx. 这样,指向整个应用程序中存储的任何文件数据的所有指针都不会因调整大小操作而失效。
我找到了问题的解决方案,但我不确定这种方法是否真的能保证在所有情况下都有效。
这是我的方法:我保留一个大的内存区域VirtualAlloc:
reserved_pages_ptr = (char*)VirtualAlloc(nullptr, MAX_FILE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
base_address = reserved_pages_ptr;
Run Code Online (Sandbox Code Playgroud)
每次调整内存映射大小时,我都会关闭旧的文件映射,释放保留的页面并保留当前文件大小不需要的其余页面:
filemapping_handle = CreateFileMappingW(...);
SYSTEM_INFO info;
GetSystemInfo(&info);
const DWORD page_size = info.dwAllocationGranularity;
const DWORD pages_needed = file_size / page_size + size_t(file_size % page_size != 0);
// release reserved pages:
VirtualFree(reserved_pages_ptr, 0, MEM_RELEASE);
// reserve rest pages:
reserved_pages_ptr = (char*)VirtualAlloc(
base_address + pages_needed * page_size,
MAX_FILE_SIZE - pages_needed * page_size,
MEM_RESERVE, PAGE_NOACCESS
);
if(reserved_pages_ptr != base_address + pages_needed * page_size)
{
//I …Run Code Online (Sandbox Code Playgroud) CreateFileMapping 错误代码 8. 没有足够的存储空间来处理此命令。我试图在 64 位 Win10 Visual C++ 上创建 4 Gb (0xFFFFFFFF) 的文件映射。
#define UBS_MEM_SIZE 0xffffffff
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个“错误 8”问题?
我正在尝试使用Windows文件映射创建一个简单的客户端 - 服务器程序,并使用信号量.客户端向服务器发送2个号码,服务器计算nr1 + nr2和nr1*nr2.我尝试了一些东西,但它甚至不适用于1个客户端,我希望它能为更多客户工作.这是代码:
服务器:
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct {
int nr1;
int nr2;
} Mesaj;
int main(int argc, char** argv) {
Mesaj* mesaj;
HANDLE createSemaphore = CreateSemaphore(NULL, 1, 1, "Semafor");
if (createSemaphore == NULL || createSemaphore == INVALID_HANDLE_VALUE) {
wcout << "Failed to create a semaphore\n";
} else {
wcout << "Created the semaphore\n";
}
HANDLE hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, sizeof(Mesaj), "SharedMemory");
WaitForSingleObject(createSemaphore, INFINITE);
mesaj = (Mesaj*) MapViewOfFile(hMemory, FILE_MAP_READ, …Run Code Online (Sandbox Code Playgroud)