2

我正在使用Qt C++我用来QSharedMemory限制应用程序的多个实例的地方来实现一个应用程序。中的相关代码段main.cpp如下,

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 */
}

打开应用程序时,我可以看到已为我的应用程序创建了共享内存。( shmid7045192, size1B)

在此处输入图像描述

到目前为止,一切都很好。当我的应用程序由于某种原因崩溃时,就会出现问题。崩溃时,sharedMemory 没有被清除,所以我无法再打开应用程序。当它崩溃时,附加的应用程序计数变为 0,但共享内存不会被删除。相关截图如下

在此处输入图像描述

据我了解,由于共享内存的状态没有dest像其他共享内存一样被标记,所以即使没有任何附加进程,它也不会被删除。

所以,我的问题是有没有办法将共享内存的状态标记为dest

4

1 回答 1

11

引用QSharedMemory文档:

使用此类时,请注意以下平台差异:

Windows:QSharedMemory 不“拥有”共享内存段。当所有将 QSharedMemory 实例附加到特定共享内存段的线程或进程都已销毁其 QSharedMemory 实例或退出时,Windows 内核会自动释放共享内存段。

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

HP-UX:每个进程只允许一个附加到共享内存段。这意味着 QSharedMemory 不应在 HP-UX 的同一进程中跨多个线程使用。

几年前我在 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
于 2017-03-02T09:09:29.193 回答