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

这篇具有很好参考价值的文章主要介绍了【Qt专栏】实现单例程序,禁止程序多开的几种方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,简要介绍

二,实现示例(Windows)

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

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

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

4.使用文件锁

5.通过网络端口检测


一,简要介绍

前言

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

目的

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

好处

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

实现方式

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

总结文章来源地址https://www.toymoban.com/news/detail-682695.html

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

二,实现示例(Windows)

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

  • 某些操作系统提供了系统级别的互斥机制,可以防止同一应用程序的多个实例运行。例如,Windows 提供了命名互斥体来实现这一点。
  • 示例模板【Qt专栏】实现单例程序,禁止程序多开的几种方式,Qt,qt,php,数据库​​​​​​​​​​​​​​
  • 示例代码
#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 进行进程间通信)【Qt专栏】实现单例程序,禁止程序多开的几种方式,Qt,qt,php,数据库​​​​​​​
  • 示例代码
#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.使用命名互斥锁(不推荐)

  • 在应用程序启动时创建一个命名互斥锁,确保只有一个实例可以获取锁,其他实例将被阻止。
  • 示例模板【Qt专栏】实现单例程序,禁止程序多开的几种方式,Qt,qt,php,数据库
  • 示例代码
#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.使用文件锁

  • 在应用程序启动时创建一个特定的文件锁,如果锁已存在,则表示已经有一个实例在运行。
  • 示例模板【Qt专栏】实现单例程序,禁止程序多开的几种方式,Qt,qt,php,数据库​​​​​​​
  • 示例代码
#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.通过网络端口检测

  • 在应用程序启动时尝试绑定到一个特定的网络端口,如果绑定成功,则表示没有其他实例正在运行。
  • 示例模板【Qt专栏】实现单例程序,禁止程序多开的几种方式,Qt,qt,php,数据库
  • 示例代码
#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专栏】实现单例程序,禁止程序多开的几种方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python 实现单例模式的几种方式以及存在的问题

    Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。 直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象 先执行了类的__new__方法(我们没写时,默认调用ob

    2024年01月22日
    浏览(45)
  • Qt 多线程的几种实现方式

    Qt多线程的实现方式有: 1. 继承QThread类,重写run()方法 2. 使用moveToThread将一个继承QObject的子类移至线程,内部槽函数均在线程中执行 3. 使用QThreadPool,搭配QRunnable(线程池) 4. 使用QtConcurrent(线程池) 为什么要用线程池? 创建和销毁线程需要和OS交互,少量线程影响不大,

    2024年02月15日
    浏览(42)
  • 禁止Ubuntu自动休眠的几种方法

    自动休眠是Ubuntu操作系统中的一项默认功能,它可以在一段时间没有用户活动时将计算机置于睡眠状态,以节省能源。然而,有时候我们希望禁用自动休眠功能,特别是在需要保持计算机处于活动状态的情况下。本文将介绍几种在Ubuntu上禁止自动休眠的方法,并提供相应的源

    2024年02月04日
    浏览(40)
  • 全网最全!!Qt实现图片旋转及图片旋转动画的几种方式

    第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: 第二种方案 使用 QPainter 这位“画家”,示例程序如下:  一、借助QPixmap实现旋转动画 第二种方案 使用 QPainter 这位“画家”,示例程序如下:

    2024年02月11日
    浏览(46)
  • 小程序对话框的几种实现方式

    在微信小程序中,有以下几种方式可以实现对话框(Dialog)的展示: 1. wx.showModal :wx.showModal 是微信小程序提供的一个API,用于显示模态对话框。模态对话框是一种阻塞式的对话框,需要用户进行交互后才能关闭。可以通过调用 wx.showModal 方法来显示对话框,并设置标题、内

    2024年02月10日
    浏览(41)
  • H5页面跳转到小程序的几种实现方法

    可以通过服务端接口或在小程序管理后台「工具」-「生成 URL Scheme」入口可以获取打开小程序任意页面的 URL Scheme 使用示例 服务端配置好接口,客户端调用接口传入目标小程序的path路径 这种适用于运行在微信环境的自定义H5页面,将跳转按钮融合在自研H5应用,点击按钮后跳

    2024年02月15日
    浏览(45)
  • 【QT深入理解】QT中的几种常用的排序函数

    排序函数是一种在编程中常用的函数,它可以对一个序列(如数组,列表,向量等)中的元素进行排序,使其按照一定的顺序排列。排序函数可以根据不同的排序算法,如冒泡排序,选择排序,插入排序,快速排序,归并排序,堆排序等,实现不同的排序效果。排序函数的作

    2024年02月03日
    浏览(47)
  • Qt 播放音频文件的几种方式

    : Qt 、 QSound 、 QSoundEffect 、 QMediaPlayer 、 multimedia 这篇文章至少拖了有一两个月了,这不阳了,在家实在是难受的要死,无心处理工作的事情,那就写写博客吧,因为项目中需要用到播放音频的功能,CV了部分代码,这里就简单的扯扯我对 QSound 、 QSoundEffect 和 QMediaP

    2024年02月11日
    浏览(42)
  • qt初入门1:qt读文件的几种方式简单整理

    工作变动开始接触qt,涉及到qt读文件相关业务,简单整理一下qt读文件几种方式,后面发现有其他的再新增 测试demo的方式归纳汇总几种读qt文件的方法 : 1:获取文件源按钮,并打印获取到的相关文件名 2:使用qfile直接读文件,显示耗时时间 3:使用qdatastream读文件,显示耗

    2024年02月12日
    浏览(39)
  • 【Qt】qDebug() 输出16进制数的几种方法

    Qt qDebug() 输出16进制数字的几种方法整理:

    2024年04月28日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包