CreateFileMapping() 即使在重新启动后也会返回"already exists";如何删除旧的命名共享内存?
CreateFileMapping() returning "already exists" even after reboot; how to remove old Named Shared Memory?
我有一系列由主exe通过使用CreateFileMapping()和MapViewOfFile()创建的命名共享内存控制的从属exe。
我正在通过Visual Studio调试Master,当我得到我需要的东西时,我只是告诉Visual Studio"停止调试"。不好的举动,因为命名共享内存保持活动状态,重新启动后它仍然存在!
我尝试通过查看错误代码来识别命名共享内存,看到它是 183(已经存在)并要求现有的命名共享内存,但失败了。
无论哪种方式,我都很乐意:在发现它已经存在时删除/删除它,或者在发现已经存在时重复使用它。目前,我被困住了。我想我可以创建一个不同的名字,但那个已经存在的该死的名字可能会永远在那里徘徊......
无论如何,下面是定义我的命名共享内存控制逻辑的C++类:
enum ServerSharedMemReturnCodes {
Success, // everything worked!
SharedMemAlreadyGrabbed, // EnableSharedMemoryAccess() error: _mapFile was not NULL!
OpenFileMappingFailed, // EnableSharedMemoryAccess() error: OpenFileMapping() filed!
MapViewOfFileFailed // EnableSharedMemoryAccess() error: MapViewOfFile() filed!
};
class ServerSharedMem {
public:
ServerSharedMem() {
_mapFile = NULL;
_serverCommLinks = NULL;
}
~ServerSharedMem() {
// Deactivate(); called explicitly at shutdown rather than here
}
/* our Named Shared Memory needs to be "activated" by the Master (installed to shared virtual memory). This does that. */
inline int Activate( void ) {
char *caller = "ServerSharedMem::Activate";
if (_mapFile != NULL) {
DebugMessage( caller, "Named Shared Memory already activated!" );
return false;
}
TCHAR smName[] = TEXT(CEX_SHAREDMEM_NAME);
int sharedMemSize = sizeof(ServerCommLink) * CEX_MAX_SERVER_COUNT;
// debug logic: print out size and name:
size_t convertedChars = 0;
char bsjnk[1024];
errno_t err = wcstombs_s( &convertedChars, bsjnk, 1024, smName, sizeof(smName));
if (err != 0) {
DebugMessage( caller, "wcstombs_s failed!" );
}
char bsjnk2[1024];
sprintf_s( bsjnk2, 1024, "sharedMemSize is '%d' bytes and smName is '%s'", sharedMemSize, bsjnk );
DebugMessage( caller, bsjnk2 ); // size is 16832, name is "GlobalCEX_ActiveTasks"
// let's create a Named Shared Memory block:
_mapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // request a paging file
NULL, // default security
PAGE_READWRITE | SEC_COMMIT, // read/write access and hold entirely in RAM
0, // high-order DWORD of max file size
sharedMemSize, // low-order DWORD of max file size
smName ); // name of our named shared memory
if (_mapFile == NULL) {
DebugMessage( caller, "failed to create Named Shared Memory!" );
DWORD errCode = GetLastError();
if (errCode == 183) { // already exists! we did not shutdown cleanly
DebugMessage( caller, "It appears to already exist! Attempting to grab it!" );
ServerSharedMemReturnCodes retCode = EnableSharedMemoryAccess();
if (retCode == Success) {
DebugMessage( caller, "Yes! Got it!" );
for (int i = 0; i < CEX_MAX_SERVER_COUNT; i++) {
_serverCommLinks[i].Init();
_serverCommLinks[i].SetServerId( i );
}
return true;
}
static CHAR errBuffer[CEX_CMDBUFFER_SIZE];
va_list errArgs[256];
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,NULL,errCode,0,errBuffer,CEX_CMDBUFFER_SIZE,errArgs);
DebugMessage( caller, errBuffer );
sprintf_s( errBuffer, CEX_CMDBUFFER_SIZE, "error code is '%d'", errCode );
DebugMessage( caller, errBuffer ); // still 183, already exists
}
/*
static CHAR errBuffer[CEX_CMDBUFFER_SIZE];
va_list errArgs[256];
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,NULL,errCode,0,errBuffer,CEX_CMDBUFFER_SIZE,errArgs);
DebugMessage( caller, errBuffer );
sprintf_s( errBuffer, CEX_CMDBUFFER_SIZE, "error code is '%d'", errCode );
DebugMessage( caller, errBuffer ); */
return false;
}
else {
_serverCommLinks = (ServerCommLink *)MapViewOfFile(_mapFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (_serverCommLinks == NULL) {
CloseHandle(_mapFile);
_mapFile = NULL;
DebugMessage( caller, "MapViewOfFile() failed!" );
return false;
}
else {
for (int i = 0; i < CEX_MAX_SERVER_COUNT; i++) {
_serverCommLinks[i].Init();
_serverCommLinks[i].SetServerId( i );
}
return true;
}
}
}
/* upon program shutdown, Named Shared Memory needs to be removed from Shared Virtual Memory. This does that. */
inline void Deactivate( void ) {
char *caller = "ServerSharedMem::Deactivate";
if (_mapFile) {
if (_serverCommLinks) {
UnmapViewOfFile( _serverCommLinks );
_serverCommLinks = NULL;
DebugMessage( caller, "Unmapped Named Shared Memory view." );
}
CloseHandle(_mapFile);
_mapFile = NULL;
DebugMessage( caller, "Closed Named Shared Memory handle." );
}
}
/* Slaves use this to gain access to the Named Shared Memory setup by their Master */
inline ServerSharedMemReturnCodes EnableSharedMemoryAccess( void ) {
if (_mapFile != NULL) {
return SharedMemAlreadyGrabbed;
}
TCHAR smName[] = TEXT(CEX_SHAREDMEM_NAME);
_mapFile = OpenFileMapping( FILE_MAP_READ | FILE_MAP_WRITE, FALSE, smName );
if (_mapFile == NULL) {
return OpenFileMappingFailed;
}
else {
_serverCommLinks = (ServerCommLink *)MapViewOfFile( _mapFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 );
return Success;
}
}
/* Slaves use this to release their hold on their view of the Named Shared Memory */
inline void ReleaseSharedMemoryAccess( void ) {
char *caller = "ServerSharedMem::ReleaseSharedMemoryAccess";
if (_mapFile != NULL) {
if (_serverCommLinks != NULL) {
UnmapViewOfFile( _serverCommLinks );
_serverCommLinks = NULL;
DebugMessage( caller, "Unmapped Named Shared Memory view." );
}
else DebugMessage( caller, "No active Named Shared Memory view!" );
CloseHandle(_mapFile);
DebugMessage( caller, "Closed Named Shared Memory handle." );
}
else DebugMessage( caller, "No Named Shared Memory!" );
}
/* pass in a return code, get back a string describing the code */
inline char *ReturnCodeInfo( ServerSharedMemReturnCodes code ) {
switch (code) {
case Success: return "Success.";
case SharedMemAlreadyGrabbed: return "Shared memory access has already been enabled.";
case OpenFileMappingFailed: return "Unable to open Named Shared Memory!";
case MapViewOfFileFailed: return "Unable to map view of Named Shared Memory!";
default: return "Unknown return code!!!";
}
}
inline int Active( void ) { return(_serverCommLinks ? true : false); }
/* returns the requested server;s communication link if Named Shared Memory is activated/enabled */
inline ServerCommLink *GetServerCommLink( int serverId ) {
if (!_serverCommLinks)
return NULL;
if ((serverId >= 0) && (serverId < CEX_MAX_SERVER_COUNT)) {
return &_serverCommLinks[serverId];
}
return NULL;
}
private:
HANDLE _mapFile; // our Named Shared Memory handle
ServerCommLink *_serverCommLinks; // will point to shared memory, an array of size CEX_MAX_SERVER_COUNT
};
Visual Studio 需要以管理员身份运行才能启动 IDE,才能具有创建命名共享对象的正确权限。
相关文章:
- 在 C++ 的自定义运算符中删除与删除[](不同于常见的删除与删除[]问题)
- C++链表删除和删除返回功能
- 从链表中删除值/删除未动态分配的值
- 当我使用dynamic_cast并删除对象删除时,析构函数是如何工作的?
- 如何在 C++ 中使用删除运算符删除单个数据
- 为什么擦除+删除比删除更有效
- 用户使用C++中的删除功能删除文件
- 删除和删除[]在内部如何工作?
- 当删除或删除[]被执行时,计算机会做什么?
- 如何在不删除C++集中删除项目?
- 如何在C 中删除或删除.jpg和.dpx图像文件
- 删除或删除 [] 在新的 int[][] 上
- 在 C++ 中使用 try-catch 进行删除 [] 或删除操作是否必要
- C++删除和删除中的逻辑[]
- 是否有任何工具可以警告可能滥用删除或删除[]
- 在函数调用中堆和删除.如何删除本地动态内存
- 删除[]与删除在for循环中
- 使用单个删除运算符删除多个指针
- 如何替换删除和删除[]
- Qt;Q删除和删除小部件.setParent(NULL)是必需的