QSharedMemory 不会在应用程序崩溃时被删除

QSharedMemory is not getting deleted on Application crash

我正在使用 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 */
}

打开应用程序后,我可以看到已经为我的应用程序创建了一个共享内存。 (shmid 7045192, size 1B)

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

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

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

引用 QSharedMemory 文档:

When using this class, be aware of the following platform differences:

Windows: QSharedMemory does not "own" the shared memory segment. When all threads or processes that have an instance of QSharedMemory attached to a particular shared memory segment have either destroyed their instance of QSharedMemory or exited, the Windows kernel releases the shared memory segment automatically.

Unix: QSharedMemory "owns" the shared memory segment. 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. But if that last thread or process crashes without running the QSharedMemory destructor, the shared memory segment survives the crash.

HP-UX: Only one attach to a shared memory segment is allowed per process. This means that QSharedMemory should not be used across multiple threads in the same process in 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