当前位置: 首页 > news >正文

【Qt专栏】实现单例程序,禁止程序多开的几种方式

目录

一,简要介绍

二,实现示例(Windows)

1.使用系统级别的互斥机制

2.通过共享内存(进程间通信-IPC)

3.使用命名互斥锁(不推荐)

4.使用文件锁

5.通过网络端口检测


一,简要介绍

前言

  • 禁止程序多开,也称为“单实例应用程序”或“单例应用程序”,是指通过各种手段防止同一个应用程序同时运行多个实例。这种方法可以提升应用程序的稳定性、资源利用效率和用户体验。

目的

  • 禁止程序多开的主要目的是确保应用程序在同一时刻只能运行一个实例,防止资源浪费、数据冲突、混淆等问题,以提高应用程序的质量和用户满意度。

好处

  1. 资源管理:多个实例同时运行可能导致资源的浪费,如内存、CPU 使用率等。通过限制只能运行一个实例,可以更有效地管理系统资源。
  2. 数据一致性:如果应用程序涉及到对共享数据或状态的修改,多个实例同时运行可能会导致数据不一致的问题。通过禁止多开,可以避免这种情况。
  3. 减少冲突:多个实例可能尝试访问同一资源,如文件、数据库等,导致冲突和错误。禁止多开可以减少这种情况的发生。
  4. 避免混淆:如果应用程序依赖于特定的硬件或外部设备,多个实例可能会导致设备混淆或竞争,从而影响功能正常运行。
  5. 提升用户体验:当用户只期望运行一个实例时,多开可能会让用户感到困惑。通过禁止多开,可以提升用户的体验和易用性。

实现方式

  1. 系统级别互斥机制:使用操作系统提供的互斥机制,如命名互斥体等。
  2. 共享内存或命名管道:使用共享内存或命名管道在不同实例间进行通信,防止多开。
  3. 命名互斥锁或文件锁:创建一个唯一名称的互斥锁或文件锁,如果已经存在,表示已有实例运行。
  4. 网络端口检测:尝试绑定到一个特定的网络端口,如果绑定成功,则表示没有其他实例在运行。
  5. 环境变量检测:检查环境变量,如已设置则表示已有实例运行。

总结

  • 总之,禁止程序多开是一种优化应用程序的方法,可以确保应用程序在不同环境中稳定、高效地运行。选择适合的实现方式取决于应用程序的需求和技术栈。

二,实现示例(Windows)

1.使用系统级别的互斥机制

  • 某些操作系统提供了系统级别的互斥机制,可以防止同一应用程序的多个实例运行。例如,Windows 提供了命名互斥体来实现这一点。
  • 示例模板​​​​​​​​​​​​​​
  • 示例代码
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <Windows.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);// L"字符串":表示将ANSI字符串转换成unicode的字符串,使每个字符占两个字节HANDLE hMutex = CreateMutex(nullptr, TRUE, (LPCWSTR)qApp->applicationName().toStdWString().c_str());if (GetLastError() == ERROR_ALREADY_EXISTS) {QMessageBox::warning(nullptr, "Error", "An instance of the application is already running.");CloseHandle(hMutex);hMutex = NULL;return 1;}// 在此处写你的应用程序逻辑代码MainWindow w;w.show();a.exec();// 完成后关闭互斥锁CloseHandle(hMutex);hMutex = NULL;return 0;
}

2.通过共享内存(进程间通信-IPC)

  • 使用进程间通信技术,例如共享内存,来检测是否已经有一个实例在运行。
  • 示例模板(使用 Qt 的 QSharedMemory 进行进程间通信)​​​​​​​
  • 示例代码
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <QSharedMemory>int main(int argc, char *argv[])
{QApplication a(argc, argv);QSharedMemory sharedMemory(qApp->applicationName());    // 设置绑定的共享内存段的key值if(sharedMemory.attach()){QMessageBox::warning(nullptr, "Error", "An instance of the application is already running.");return 1;}else{sharedMemory.create(1); // 创建1byte大小的共享内存段}// 在此处写你的应用程序逻辑代码MainWindow w;w.show();a.exec();// 完成后分离共享内存sharedMemory.detach();return 0;
}

3.使用命名互斥锁(不推荐)

  • 在应用程序启动时创建一个命名互斥锁,确保只有一个实例可以获取锁,其他实例将被阻止。
  • 示例模板
  • 示例代码
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <QSystemSemaphore>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 声明一个命名互斥锁,用于防止多开QSystemSemaphore semaphore(qApp->applicationName(), 1, QSystemSemaphore::Open);if (!semaphore.acquire()) {QMessageBox::warning(nullptr, "Error", "An instance of the application is already running.");return 1;}// 在此处写你的应用程序逻辑代码MainWindow w;w.show();a.exec();// 释放互斥锁,允许其他实例运行semaphore.release();return 0;
}

4.使用文件锁

  • 在应用程序启动时创建一个特定的文件锁,如果锁已存在,则表示已经有一个实例在运行。
  • 示例模板​​​​​​​
  • 示例代码
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <QFile>int main(int argc, char *argv[])
{QApplication a(argc, argv);QFile lockFile(qAppName() +".lock");if (lockFile.exists()) {QMessageBox::warning(nullptr, "Error", "An instance of the application is already running.");return 1;}lockFile.open(QIODevice::WriteOnly);lockFile.write("Running"); // 向锁文件写入一些数据lockFile.close();// 在此处写你的应用程序逻辑代码MainWindow w;w.show();a.exec();// 完成后删除锁定文件lockFile.remove();return 0;
}

5.通过网络端口检测

  • 在应用程序启动时尝试绑定到一个特定的网络端口,如果绑定成功,则表示没有其他实例正在运行。
  • 示例模板
  • 示例代码
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <QTcpServer>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTcpServer tcpServer;if (!tcpServer.listen(QHostAddress::LocalHost, 12345)) {QMessageBox::warning(nullptr, "Error", "An instance of the application is already running.");return 1;}// 在此处写你的应用程序逻辑代码MainWindow w;w.show();a.exec();// 完成后关闭服务器tcpServer.close();return 0;
}

相关文章:

【Qt专栏】实现单例程序,禁止程序多开的几种方式

目录 一&#xff0c;简要介绍 二&#xff0c;实现示例&#xff08;Windows&#xff09; 1.使用系统级别的互斥机制 2.通过共享内存&#xff08;进程间通信-IPC&#xff09; 3.使用命名互斥锁&#xff08;不推荐&#xff09; 4.使用文件锁 5.通过网络端口检测 一&#xf…...

力扣26. 删除有序数组中的重复项

给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你需要做…...

【机器学习】鸢尾花分类-逻辑回归示例

这段代码是一个完整的示例&#xff0c;展示了如何使用逻辑回归对鸢尾花数据集进行训练、保存模型&#xff0c;并允许用户输入数据进行预测。以下是对这段代码的总结&#xff1a;功能&#xff1a; 这段代码演示了如何使用逻辑回归对鸢尾花数据集进行训练&#xff0c;并将训练好的…...

Flink CDC介绍

1.CDC概述 CDC&#xff08;Change Data Capture&#xff09;是一种用于捕获和处理数据源中的变化的技术。它允许实时地监视数据库或数据流中发生的数据变动&#xff0c;并将这些变动抽取出来&#xff0c;以便进行进一步的处理和分析。 传统上&#xff0c;数据源的变化通常通过…...

Java集合sort排序报错UnsupportedOperationException处理

文章目录 报错场景排查解决UnmodifiableList类介绍 报错场景 我们使用的是PostgreSQL数据库&#xff0c;存储业务数据&#xff0c;业务代码使用的是Spring JPA我们做的是智慧交通信控平台&#xff0c;有个功能是查询展示区域的交通态势&#xff0c;需要按照不同维度排序展示区…...

安防监控/磁盘阵列存储/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?

安防监控/云存储/磁盘阵列存储/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RT…...

Spring boot开启定时任务

Cron表达式生成器 基于接口的方式 使用Scheduled 注解很方便&#xff0c;但缺点是当我们调整了执行周期的时候&#xff0c;需要重启应用才能生效&#xff0c;这多少有些不方便。为了达到实时生效的效果&#xff0c;那么可以使用接口来完成定时任务&#xff0c;统一将定时器信…...

package.json相关知识记录

一、相关字段 npm官方字段介绍 &#x1f367; bin   >   简单理解&#xff1a;指定命令的名称及路径   &#x1f349; 相当于想path中添加路径&#xff0c;局部安装是在./node_modules/.bin/&#xff0c;全局安装是在全局的bin目录   &#x1f349; bin指定的文件必须…...

VueRouter使用详解(5000字通关大全)

Vue Router是一个官方的路由管理器&#xff0c;它可以让我们在Vue应用中实现单页面应用&#xff08;SPA&#xff09;的效果&#xff0c;即通过改变URL而不刷新页面来显示不同的内容。Vue Router可以让我们定义多个路由&#xff0c;每个路由对应一个组件&#xff0c;当URL匹配到…...

vue axios实现下载文件及responseType:blob注意事项

需要使用axios和js-file-download组件 npm install js-file-download --save npm install axios --save import fileDownload from fileDownload; // 引入fileDownload import axios from axios; // 引入axios axios({method: get,url: xxxxxxx,responseType: blob }).then(r…...

StringBuilder类分享(1)

一、StringBuilder说明 StringBuilder是一个可变的字符序列。这个类提供了一个与StringBuffer兼容的API&#xff0c;但不保证同步&#xff0c;即StringBuilder不是线程安全的&#xff0c;而StringBuffer是线程安全的。显然&#xff0c;StringBuilder要运行的更快一点。 这个类…...

Qt 打开文件列表选择文件,实现拖拽方式打开文件

1. 实现打开文件列表选择文件 1.1. 创建 Qt 工程&#xff0c;并添加几个简单控件 这里笔者选用的是 QMainWindow&#xff0c;创建好工程后在 ui 界面设计中添加 QLineEdit、QPushBtton至少这两个控件&#xff0c;如下图摆放。 1.2. 头文件中添加相关操作 在 mainwindow.h 中…...

[C/C++]天天酷跑游戏超详细教程-上篇

个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;大家一起学习交流&#xff01;&#x1f9…...

5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源

PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4&#xff0c;需要注意根据实际情况在这三张表中进行选择&#xff1a; FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…...

在vue3项目中编辑的时候,解决对话框里边的数据和列表中的数据联动了。深复制

//分析原因是从列表中拿到的数据直接复制去修改就涉及到堆里变的内容是一样的&#xff0c;直接复制其实只是把引用地址赋值给变量了&#xff0c;解决方法是 浅复制和深复制。<!-- 审批流程管理 --> <template><div style"float: left; width: 250px;backgr…...

循环结构(个人学习笔记黑马学习)

while循环语句 在屏幕中打印0~9这十个数字 #include <iostream> using namespace std;int main() {int i 0;while (i < 10) {cout << i << endl;i;}system("pause");return 0; } 练习案例: 猜数字 案例描述:系统随机生成一个1到100之间的数字&…...

ceph中PGLog处理流程

正文 struct pg_log_entry_t {ObjectModDesc mod_desc; //用于保存本地回滚的一些信息&#xff0c;用于EC模式下的回滚操作bufferlist snaps; //克隆操作&#xff0c;用于记录当前对象的snap列表hobject_t soid; …...

macOS使用命令行连接Oracle(SQL*Plus)

Author: histonevonzohomail.com Date: 2023/08/25 文章目录 SQL\*Plus安装下载环境配置 SQL\*Plus远程连接数据库参考文献 原文地址&#xff1a;https://histonevon.top/archives/oracle-mac-sqlplus数据库安装&#xff1a;Docker安装Oracle数据库 (histonevon.top) SQL*Plus…...

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…...

centos安装Nginx配置Nginx

1. 查看操作系统有没有安装Nginx which nginx 2. 使用epel的方式进行安装&#xff08;方法二&#xff09; 先安装epel sudo yum install yum-utils 安装完成后&#xff0c;查看安装的epel包即可 sudo yum install epel 3 开始安装nginx 上面的两个方法不管选择哪个&…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...