首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++共享内存泄漏,如何清除共享内存?

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

Stack Overflow用户
提问于 2011-10-14 20:34:40
回答 3查看 6.9K关注 0票数 5

我正在使用Qt,并试图通过在Linux(ubuntu).中应用解决方案来实现单个实例应用程序。问题是,如果应用程序意外完成(Seg)。共享内存仍然是附加的,没有其他进程可以再次创建它。从QSharedMemory文档中召回:

Unix: QSharedMemory“拥有”共享内存段。当最后一个将QSharedMemory实例附加到特定共享内存段的线程或进程通过销毁其QSharedMemory实例而与该段分离时,Unix内核将释放共享内存段。但是,如果最后一个线程或进程在没有运行QSharedMemory析构函数的情况下崩溃,则共享内存段将幸免于难。

代码语言:javascript
复制
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(); 
}

你能在这里提出什么解决方案?如何确保共享内存(或任何通常使用的动词)在进程最终结束后被清除。我需要类似于java中的finally之类的东西,主要功能是:/

编辑:(解决方案)

通过使用QSharedMemory并捕获SIGSEGV信号,然后在信号处理程序中调用sharedMemory.detach(),我已经达到了预期的行为。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-14 20:40:45

您可以捕获程序崩溃的信号,并使用调用QSharedMemory析构函数的处理程序。

票数 6
EN

Stack Overflow用户

发布于 2011-10-14 21:21:21

事实是,如果您的程序需要被杀死或有分段错误,那么您就不能对它做任何事情。共享内存并不是确保UNIX/Linux下应用程序的单个实例的最佳选择。尝试使用信号量代替,因为一旦应用程序终止,它们就会被关闭。

编辑:

来自的文档

在进程终止或execve(2)时,所有打开的命名信号量都会自动关闭。

我还必须补充一点,确保单应用程序违禁品可能会对linux这样的系统产生奇怪的后果--假设有人通过ssh使用X隧道登录并尝试启动应用程序--如果有人已经在使用它,它就不会启动。这将是相当大的收割机。您是应用程序开发人员,如果您需要每个系统的每个用户,甚至每个X会话封锁,您应该知道最好。

如果要使用每个用户的封锁,则解决方案可能是在包含当前pid的用户主目录中添加隐藏文件。下一个应用程序将检查该文件,如果该文件存在,并且/proc/pid/exe链接指向当前二进制文件,则返回错误。

票数 1
EN

Stack Overflow用户

发布于 2013-03-13 06:55:33

您可以在程序结束后运行脚本,手动清除系统上的共享内存、信号量等(我的是运行10.8的Mac )。在运行使用QSharedMemory的程序时,我已经插入了一个脚本,并在程序意外退出并使共享内存实例“挂起”时使用。

记住,这将删除与用户名相关的所有共享内存实例。如果有多个程序运行并使用共享内存实例,则应等到每个程序完成后再执行,或者根据需要调整脚本,仅删除由程序创建的共享内存实例。

代码语言:javascript
复制
#!/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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7773276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档