1
我有一系列Slave exe由Master exe控制,通過使用CreateFileMapping()和MapViewOfFile()創建的命名共享內存。即使重新啓動後,CreateFileMapping()返回「已經存在」如何刪除舊的命名共享內存?
我正在通過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
};
您是否嘗試過從處理例程的錯誤代碼183中調用'OpenFileMapping'並查看是否可以獲取句柄?道歉,如果你有,但它不在你的代碼中的問題。 –
是的。如果您遵循errCode == 183邏輯,它會調用EnableSharedMemoryAccess(),這是同一個類中的另一種方法,並嘗試使用OpenFileMapping()來獲取已存在的命名共享內存。這也失敗了。 –
我只是嘗試使用不同的名稱,只是爲了看看我能否繼續工作,但也失敗了。還有一些其他的事情正在發生,因爲這個邏輯已經工作了幾個星期了......我只是爲了一個Windows更新...希望一些更新的操作系統不管是什麼原因...... –