繁体   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