简体   繁体   English

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

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

I am using Qt and trying to achieve a single instance application by applying this solution in Linux(ubuntu) . 我正在使用Qt并尝试通过在Linux(ubuntu)中应用解决方案来实现单实例应用程序。 The problem is that if the application unexpectedly finishes(seg. fault or user kills it) the shared memory remains attached and no other process can create it again. 问题是,如果应用程序意外完成(seg。错误或用户杀死它),共享内存将保持连接状态,其他任何进程都无法再次创建它。 Recall from QSharedMemory doc: 回想一下QSharedMemory doc:

Unix: QSharedMemory "owns" the shared memory segment. Unix:QSharedMemory“拥有”共享内存段。 When the last thread or process that has an instance of QSharedMemory attached to a particular shared memory segment detaches from the segment by destroying its instance of QSharedMemory, the Unix kernel release the shared memory segment. 当具有附加到特定共享内存段的QSharedMemory实例的最后一个线程或进程通过销毁其QSharedMemory实例而从该段中分离时,Unix内核将释放共享内存段。 But if that last thread or process crashes without running the QSharedMemory destructor, the shared memory segment survives the crash. 但是如果最后一个线程或进程在没有运行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(); 
}

What solutions can you suggest here? 你能在这里建议什么解决方案? How can I assure that the shared memory is cleared(or whatever verb used generally) after the process eventually finishes. 在流程最终​​完成后,如何确保共享内存被清除(或者通常使用的任何动词)。 I need something like finally in java all around the main function :/ 我需要这样的东西finally在Java各地的主要功能:/

EDIT: (Solution) 编辑:(解决方案)

I have achieved the desired behavior by using QSharedMemory and catching SIGSEGV signal then call sharedMemory.detach() in the signal handler. 我已经通过使用QSharedMemory并捕获SIGSEGV信号然后在信号处理程序中调用sharedMemory.detach()来实现所需的行为。

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

You could always run a script after termination of your program to manually clear the shared memory, semaphores, etc. on your system (mine is a Mac Pro running 10.8). 您可以在程序终止后运行脚本,以手动清除系统上的共享内存,信号量等(我的是运行10.8的Mac Pro)。 I have inserted a script I use for this when running programs that use QSharedMemory, and use it when the program quits unexpectedly and leaves the shared memory instances "hanging". 我在运行使用QSharedMemory的程序时插入了我用于此的脚本,并在程序意外退出并使共享内存实例“挂起”时使用它。

Keep in mind this will remove all shared memory instances associated with your user name. 请记住,这将删除与您的用户名关联的所有共享内存实例。 If you have multiple programs running and using shared memory instances, you should either wait until every program is done, or adjust the script as needed to only delete the shared memory instances that were created by your program. 如果有多个程序正在运行并使用共享内存实例,则应该等到每个程序完成,或者根据需要调整脚本以仅删除程序创建的共享内存实例。

#!/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

Truth is that if your program needs to be killed or has a segfault, then you cannot really do anything about it. 事实是,如果你的程序需要被杀死或有段错误,那么你无法真正做任何事情。 Shared memory is not the best choice for ensuring single instance of appliction under UNIX/Linux. 共享内存不是确保UNIX / Linux下单个应用程序实例的最佳选择。 Try using semaphores instead, as they are getting closed as soon as your application terminates. 尝试使用信号量,因为它们会在应用程序终止后立即关闭。

EDIT: 编辑:

From documentation of sem_close 来自sem_close的文档

All open named semaphores are automatically closed on process termination, or upon execve(2). 所有打开的命名信号量在进程终止时或execve(2)时自动关闭。

I also must add that ensuring single-app contraint might have weird consequences on system like linux - imagine somebody logged via ssh with X tunneling and trying to start your app - if somebody is already using it, it will not start. 我还必须补充一点,确保单应用程序约束可能会对像linux这样的系统产生奇怪的后果 - 想象有人通过ssh使用X隧道进行登录并尝试启动你的应用程序 - 如果某人已经在使用它,它将无法启动。 This will be rather confisunig. 这将是相当混乱的。 You are application developer and should know best if you need per-system per-user or even per-X-session blockade. 您是应用程序开发人员,如果您需要每个系统的每个用户甚至每个X-session阻止,那么您应该最了解。

If you want to use per-user blockade, then solution might be to add hidden file in user home directory containing current pid. 如果要使用每用户阻止,则解决方案可能是在包含当前pid的用户主目录中添加隐藏文件。 Next application will check for this file, and if it exists AND /proc/[pid]/exe link points to current binary, then return error. 下一个应用程序将检查此文件,如果它存在并且/ proc / [pid] / exe链接指向当前二进制文件,则返回错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM