qt程序设置同时只能运行一个,避免重复打开
- [1] qt程序设置同时只能运行一个,避免重复打开
- [2] Qt 桌面软件防止重新启动
- 一、创建互斥量
- 二、使用QLockFile 创建锁定文件,通过能否锁定来判断是否已经有程序启动。
- 三、使用 系统信号量 QSystemSemaphore 与 共享内存 QSharedMemory
- [3] Qt 编写的程序如何只能运行一个实例
- [4] linux qt 只运行一个实例,Qt 只运行一个程序实例
[1] qt程序设置同时只能运行一个,避免重复打开
原文链接:https://blog.csdn.net/WMT1520/article/details/127207867
在main.cpp文件中加入以下头文件
//头文件
#include <QSharedMemory>
#include <QMessageBox>
在主界面显示之前,创建共享内存块,并进行判断
static QSharedMemory *singleApp = new QSharedMemory("SingleApp");//创建“SingleApp”的共享内存块
if(!singleApp->create(1))//创建失败,说明已经有一个程序运行,
{
QMessageBox::information(NULL,"tips","The program is already running");//弹出提示框 注意:该提示应该在 qApp->quit();之前,否则提示框将会一闪而过
qApp->quit();//退出当前程序
return -1;
}
QSharedMemory的使用参考:https://doc.qt.io/qt-6/qsharedmemory.html
[2] Qt 桌面软件防止重新启动
原文链接:https://blog.csdn.net/xiezhongyuan07/article/details/120286676
越来越多的 windows 桌面程序要求防止重复启动,或者说只允许同时启动一个。实现方式有很多,我们接下来梳理一下常用的做法:
一、创建互斥量
原理:使用 windows 系统函数 CreateMutex ,一般根据唯一的应用程序的名称来找出当前系统中是否已经存在了指定进程的实例,如果没有,则会创建一个。
注意: 程序退出时,一定要调用CloseHandle(m_hMutex),不然后果很严重,可能导致以后的程序无法打开。
#include "stdafx.h"
#include "windows.h"
int main(int argc, char* argv[])
{
HANDLE m_hMutex = CreateMutex(NULL, TRUE, "my_app_name");
DWORD dwRet = GetLastError();
if (m_hMutex) {
if (ERROR_ALREADY_EXISTS == dwRet)
{
printf("程序已经在运行中了,程序退出!\n");
CloseHandle(m_hMutex);
return 0;
}
} else {
printf("创建互斥量错误,程序退出!\n");
CloseHandle(m_hMutex);
return 0;
}
while(1) {
printf("my_app_name\n");
}
CloseHandle(m_hMutex);
return 0;
}
二、使用QLockFile 创建锁定文件,通过能否锁定来判断是否已经有程序启动。
原理:使用Qt 提供的对象 QLockFile。它提供一个文件的进程间的锁定。锁文件可用于防止多个进程同时访问统一资源。只有当访问共享资源的所有进程使用相同的文件路径的QLockFile时,才能保证序列化。 使用使用 tryLock() 函数来尝试锁定文件,锁定成功了,就说明没有已经启动的程序。锁定失败则表示已经有程序在启动了。
注意:
-
创建一个临时文件(一般创建在临时目录内)。
-
一般使用tryLock 要设置超时时间,时间一般不易过久。
#include <QApplication>
#include <QLockFile>
#include <QDir>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString tempPath = QApplication::applicationDirPath() + "/temp/";
QString filePath = tempPath + "/" + "my_app_name" + ".app.lock";
QLockFile *lockFile = new QLockFile(filePath);
if (lockFile->tryLock(2000)) {
qDebug() << "运行程序成功!";
} else {
qDebug() << "程序已经在运行中了,程序退出";
return 0 ;
}
if (lockFile) {
delete lockFile;
}
return a.exec();
}
三、使用 系统信号量 QSystemSemaphore 与 共享内存 QSharedMemory
原理:
- 信号量 QSystemSemaphore: 为系统级别信号量,可以再多个进程间使用。多个进程可以通过名字来操作一个信号量。创建时候需要指定一个mode,可以选择Open 和 Create 。其中,Open在请求的信号量已存在时,就使用它,并且不会重置信号的资源数,如果请求的信号量不存在,就 创建它并为它设置初始的资源值。而对于Create来说,不管请求的信号量是否已存在,它都会取得信号量的拥有权,并设置初始值。所以,我们应该在第一次创建信号量时,为其传入Create参数。但在Windows平台上,Create和Open的行为相同,因为,Windows平台上不存在应用程序崩溃后,信号量还存在的情况。
信号量简单的来说就是谁先请求,谁就可以继续操作,只有释放了之后,别的程序才可以继续。所以信号量也可以理解为一种简单的互斥锁,保护某种资源不会同时被多个程序操作。
使用系统信号量就是为了保护共享内存不会被多个进程同时操作。
注意:
信号量的启动 acquire() 和释放 release() 必须是成对出现。要保护资源的操作要在 acquire() 和 release() 中间操作。
#include <QApplication>
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建信号量
QSystemSemaphore semaphore("myAppSemaphore", 1);
// 启用信号量,禁止其他实例通过共享内存一起工作
semaphore.acquire();
// 创建一个共享内存 myAppName 可作为唯一程序的标识
QSharedMemory sharedMemory1("myAppName");
bool isRunning = false;
// 试图将共享内存的副本附加到现有的段中。
if (sharedMemory1.attach()) {
// 如果成功,则确定已经存在运行实例
isRunning = true;
} else {
// 否则申请一字节内存
sharedMemory1.create(1);
// 确定不存在运行实例
isRunning = false;
}
semaphore.release();
if (isRunning) {
qDebug() << "程序已经在运行中了,程序退出";
return 0;
}
return a.exec();
}
[3] Qt 编写的程序如何只能运行一个实例
https://blog.csdn.net/liyuanbhu/article/details/126563321
[4] linux qt 只运行一个实例,Qt 只运行一个程序实例
https://blog.csdn.net/weixin_34805229/article/details/116692219