簡體   English   中英

C ++共享內存泄漏,如何清除共享內存?

[英]C++ shared memory leak, how to clear shared memory?

我正在使用Qt並嘗試通過在Linux(ubuntu)中應用解決方案來實現單實例應用程序。 問題是,如果應用程序意外完成(seg。錯誤或用戶殺死它),共享內存將保持連接狀態,其他任何進程都無法再次創建它。 回想一下QSharedMemory doc:

Unix:QSharedMemory“擁有”共享內存段。 當具有附加到特定共享內存段的QSharedMemory實例的最后一個線程或進程通過銷毀其QSharedMemory實例而從該段中分離時,Unix內核將釋放共享內存段。 但是如果最后一個線程或進程在沒有運行QSharedMemory析構函數的情況下崩潰,那么共享內存段將在崩潰中幸存下來。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Ensure single instanse of Cevirgec application
    QSharedMemory shared(ApplicationConstants::

    if( !shared.create( 512, QSharedMemory::ReadWrite) )
    {
      // QMessageBox msgBox;
      QMessageBox::critical(0, QObject::tr("application is already running!"), QObject::tr("application is already running!"), QMessageBox::Ok, QMessageBox::Ok);
      qCritical() << "application is already running!";

      exit(0);
    }
    else {
        qDebug() << "application staring...";
    }
    return a.exec(); 
}

你能在這里建議什么解決方案? 在流程最終​​完成后,如何確保共享內存被清除(或者通常使用的任何動詞)。 我需要這樣的東西finally在Java各地的主要功能:/

編輯:(解決方案)

我已經通過使用QSharedMemory並捕獲SIGSEGV信號然后在信號處理程序中調用sharedMemory.detach()來實現所需的行為。

您可以捕獲導致程序崩潰的信號,並使用調用QSharedMemory析構函數的處理程序。

您可以在程序終止后運行腳本,以手動清除系統上的共享內存,信號量等(我的是運行10.8的Mac Pro)。 我在運行使用QSharedMemory的程序時插入了我用於此的腳本,並在程序意外退出並使共享內存實例“掛起”時使用它。

請記住,這將刪除與您的用戶名關聯的所有共享內存實例。 如果有多個程序正在運行並使用共享內存實例,則應該等到每個程序完成,或者根據需要調整腳本以僅刪除程序創建的共享內存實例。

#!/bin/bash

ME=$(whoami)

IPCS_S=$(ipcs -s | grep $ME | sed "s/  / /g" | cut -f2 -d " ")
IPCS_M=$(ipcs -m | grep $ME | sed "s/  / /g" | cut -f2 -d " ")
IPCS_Q=$(ipcs -q | grep $ME | sed "s/  / /g" | cut -f2 -d " ")

echo "Clearing Semaphores"
for id in $IPCS_S
do
    ipcrm -s $id
done

echo "Clearing Shared Memory"
for id in $IPCS_M 
do
    ipcrm -m $id
done

echo "Clearing Message Queues"
for id in $IPCS_Q
do
    ipcrm -q $id
done

事實是,如果你的程序需要被殺死或有段錯誤,那么你無法真正做任何事情。 共享內存不是確保UNIX / Linux下單個應用程序實例的最佳選擇。 嘗試使用信號量,因為它們會在應用程序終止后立即關閉。

編輯:

來自sem_close的文檔

所有打開的命名信號量在進程終止時或execve(2)時自動關閉。

我還必須補充一點,確保單應用程序約束可能會對像linux這樣的系統產生奇怪的后果 - 想象有人通過ssh使用X隧道進行登錄並嘗試啟動你的應用程序 - 如果某人已經在使用它,它將無法啟動。 這將是相當混亂的。 您是應用程序開發人員,如果您需要每個系統的每個用戶甚至每個X-session阻止,那么您應該最了解。

如果要使用每用戶阻止,則解決方案可能是在包含當前pid的用戶主目錄中添加隱藏文件。 下一個應用程序將檢查此文件,如果它存在並且/ proc / [pid] / exe鏈接指向當前二進制文件,則返回錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM