感谢这位博主: https://blog.csdn.net/xinluo7/article/details/118226389
在Windows系统下,当程序出现崩溃,虽然没有主动调用QSharedMemory.attach() ,但是系统会自动回收QSharedMemory共享内存内核对象。
在Linux系统下,当程序崩溃后,因为没有执行QSharedMemory的析构函数,相当于是没有调用QSharedMemory.attach(),结果共享内核对象没有释放,linux也不会帮你回收。
为了让Qt程序能够同时只运行一个,通常我们只需要在main函数中添加如下代码:
QSharedMemory shared("XXXXX_QSharedMemory_Running");
if (shared.attach()) return 0;
shared.create(1);
这段代码,在Windows上出现程序崩溃后,能够再次启动程序,但是在Linux上,却是不可以的,原因上面已经解释了:就是Wndows会帮你自动回收内核对象,而Linux不会,这就导致在Linux中,这段共享内存一直存在,直到调用了attach。
针对上述现象,更改如下:
QSharedMemory shared("DobotCalibrate_QSharedMemory_Running");
if (!shared.create(1))
{
printf("the first time to create shared memory fail:%s\n",shared.errorString().toStdString().c_str());
if (shared.error()==QSharedMemory::AlreadyExists)
{
shared.attach();
shared.detach();
if (!shared.create(1))
{
printf("the second time to create shared memory fail:%s\n",shared.errorString().toStdString().c_str());
printf("app start fail,because the app is running!!!!!\n");
return 0;
}
}
}
printf("app starting.......\n");
先create,失败了,然后根据错误码判断已经存在,然后attach一次,将当前进程附着在这个共享内存上,然后detach。最后再创建,如果还是失败,说明进程确实在运行。