2017-03-02 267 views
1

我正在使用Qt C++實現應用程序,其中我使用QSharedMemory來限制應用程序的多個實例。在main.cpp相關代碼段如下,QSharedMemory在應用程序崩潰時未被刪除

QSharedMemory sharedMemory; 
sharedMemory.setKey(SM_INSTANCE_KEY); 

if (!sharedMemory.create(1)) 
{ 
    QMessageBox::warning(0, "Console", "An instance of this application is already running!"); 
    exit(0); /* Exit, already a process is running */ 
} 

在打開的應用程序,我可以看到一個共享內存已經爲我的應用程序創建的。 (shmid 7045192,size 1B)

enter image description here

到目前爲止好。由於某種原因,我的應用程序崩潰時出現問題。崩潰時,sharedMemory沒有被清除,所以我無法再打開該應用程序。當它崩潰時,連接的應用程序數量變爲0,但共享內存不會被刪除。相關截屏如下所示

enter image description here

按我的理解,作爲共享存儲器的狀態沒有被標記爲dest像其他共同的記憶,它是在沒有任何沒有得到,甚至刪除附加過程。

所以,我的問題是,是否有任何方式標記共享內存的狀態爲dest

回答

4

報價QSharedMemory文檔:

當使用這個類,要注意以下平臺的差異:

的Windows:QSharedMemory沒有 「自己的」 共享內存段。當具有連接到特定共享內存段的QSharedMemory 實例的所有線程或進程已銷燬 QSharedMemory的實例或退出時,Windows內核會自動釋放共享內存段 。

Unix:QSharedMemory「擁有」共享內存段。當具有QSharedMemory實例的最後一個線程或進程附加到特定共享內存段的 與該段分離 銷燬其QSharedMemory實例時,Unix內核將釋放 共享內存段。但是,如果最後一個線程或進程崩潰 而不運行QSharedMemory析構函數,共享內存 段倖存下來的崩潰。

HP-UX:每個進程只允許一個連接到共享內存段。這意味着在HP-UX的同一進程中,不應在多個線程中使用QSharedMemory。

我已經添加幾年前Linux上的同樣的問題,我們通過做這些步驟解決了這個問題:

// Pseudo code 
if (create_share_memory() == failed) 
{ 
    // The failure may be caused by the shm already existing 
    attach() 
    detach() // This should delete the shm if no process use it 
    if (create_share_memory() == failed) 
    { 
     // We really cannot create the share memory, report the error 
     return failed 
    } 
} 
return ok 
+0

這確實是很好的解決方案。它工作完美。謝謝。 –

+0

好的解決方法,謝謝。 –

+0

您還可以: 1- Init shm 2- attach/detach 3-如果您可以創建 ,請點擊此處。這樣它更具可讀性,而且你沒有x2'if'。但是,謝謝,這個修復節省了我的一天! – user2629409