2012-10-03 13 views
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 
}; 
+0

您是否嘗試過從處理例程的錯誤代碼183中調用'OpenFileMapping'並查看是否可以獲取句柄?道歉,如果你有,但它不在你的代碼中的問題。 –

+0

是的。如果您遵循errCode == 183邏輯,它會調用EnableSharedMemoryAccess(),這是同一個類中的另一種方法,並嘗試使用OpenFileMapping()來獲取已存在的命名共享內存。這也失敗了。 –

+0

我只是嘗試使用不同的名稱,只是爲了看看我能否繼續工作,但也失敗了。還有一些其他的事情正在發生,因爲這個邏輯已經工作了幾個星期了......我只是爲了一個Windows更新...希望一些更新的操作系統不管是什麼原因...... –

回答

0

需要以管理員身份運行Visual Studio才能啓動Visual Studio,以具有創建指定共享對象的正確權限。

相關問題