Qt-应用程序单实例的实现

实现应用程序单实例的三个方法

  1. 共享内存(QSharedMemory);
  2. QLocalServer;
  3. QtSingleApplication。

共享内存

原理

创建同一块Key的共享内存,在有多个应用程序时,可以在无需create的情况下attach,以此判断是否有多个应用程序实例。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <QCoreApplication>
#include <QSharedMemory>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 构造函数设置key,也可以使用setKey
QSharedMemory sharedMemory("testForSharedMemory");
// 如果能直接访问
if(sharedMemory.attach())
return 0;
// 不能直接访问则创建
sharedMemory.create(1);
MainWindow w;
w.show();
return a.exec();
}

使用注意

Unix操作系统中,如果最后一个线程或进程在没有运行~QSharedMemory()的情况下崩溃,共享内存段会在崩溃时幸存下来。

QLocalServer

原理

QLocalServer提供一个基于本地socketserver,可以通过设置对应key连接对应Server,以判断唯一实例。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <QLocalServer>
#include <QLocalSocket>
#include <QString>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString serverName = "localServer";
QLocalSocket socket;
socket.connectToServer(serverName);
// 连接成功,说明已经有在运行的Server实例
if(socket.waitForConnected(1000))
return 0;
QLocalServer server;
if (server.listen(serverName))
{
// 监听失败,可能是程序崩溃时,残留进程服务导致的,将其移除
if(server.serverError()== QAbstractSocket::AddressInUseError)
{
QLocalServer::removeServer(serverName);
server.listen(serverName);
}
}

QtSingleApplication

来源

Qt官方提供的Qt-Solutions中的项目,长期维护中。

原理

有关QtSingleApplication详情见此处

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <qtsingleapplication.h>
int main(int argc, char** argv)
{
// 自定义的程序标记,由这个标记去区别实例。如果不指定,则会以qApp->applicationFilePath()做为标记
const QString APP_ID("app id");
QtSingleApplicion app(APP_ID, argc, argv);
// 如果已经有实例运行
if(app.isRunning())
{
return 0;
}
MainWindow w;
w.show();
return app.exec();
}