我有一系列由主 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 "Global\CEX_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
};