Qt之运行一个实例进程-阿里云开发者社区

开发者社区> 潘志闻> 正文

Qt之运行一个实例进程

简介: 简述 发布程序的时候,我们往往会遇到这种情况: 只需要用户运行一个实例进程 用户可以同时运行多个实例进程 一个实例进程的软件有很多,例如:360、酷狗… 多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ… 下面我们来介绍下如何实现一个实例进程。 简述 QSharedMemory QLocalServer QtSing
+关注继续查看

简述

发布程序的时候,我们往往会遇到这种情况:

  1. 只需要用户运行一个实例进程
  2. 用户可以同时运行多个实例进程

一个实例进程的软件有很多,例如:360、酷狗…
多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ…

下面我们来介绍下如何实现一个实例进程。

QSharedMemory

使用共享内存来实现,key值唯一,一般可以用组织名+应用名来确定。

首先,创建一个共享内存区,当第二个进程启动时,判断内存区数据是否建立,如果有,可以激活已打开的窗体,也可以退出。

当程序crash的时候,不能及时清除共享区数据,导致程序以后不能正常启动。

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QCoreApplication::setOrganizationName("Company");
    QCoreApplication::setApplicationName("AppName");
    QString strKey = QCoreApplication::organizationName() + QCoreApplication::applicationName();

    QSharedMemory sharedMemory(strKey);
    if (!sharedMemory.create(512, QSharedMemory::ReadWrite))
    {
        QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
        exit(0);
    }

    MainWindow window;
    window.show();

    return app.exec();
}

QLocalServer

QSingleApplication.h

#ifndef SINGLE_APPLICATION_H
#define SINGLE_APPLICATION_H

#include <QApplication>

class QLocalServer;

class QSingleApplication : public QApplication
{
    Q_OBJECT

public:
    explicit QSingleApplication(int argc, char **argv);
    // 判断进程是否存在
    bool isRunning();

private slots:
    void newLocalConnection();

private:
    QLocalServer *m_pServer;
    bool m_bRunning;
};

#endif // SINGLE_APPLICATION_H

QSingleApplication.cpp

#include <QLocalSocket>
#include <QLocalServer>
#include <QFile>
#include <QTextStream>
#include "QSingleApplication.h"

QSingleApplication::QSingleApplication(int argc, char **argv)
    : QApplication(argc, argv),
      m_bRunning(false)
{
    QCoreApplication::setOrganizationName("Company");
    QCoreApplication::setApplicationName("AppName");
    QString strServerName = QCoreApplication::organizationName() + QCoreApplication::applicationName();

    QLocalSocket socket;
    socket.connectToServer(strServerName);

    if (socket.waitForConnected(500))
    {
        QTextStream stream(&socket);
        QStringList args = QCoreApplication::arguments();

        QString strArg = (args.count() > 1) ? args.last() : "";
        stream << strArg;
        stream.flush();
        qDebug() << "Have already connected to server.";

        socket.waitForBytesWritten();

        m_bRunning = true;
    }
    else
    {
        // 如果不能连接到服务器,则创建一个
        m_pServer = new QLocalServer(this);
        connect(m_pServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));

        if (m_pServer->listen(strServerName))
        {
            // 防止程序崩溃,残留进程服务,直接移除
            if ((m_pServer->serverError() == QAbstractSocket::AddressInUseError) && QFile::exists(m_pServer->serverName()))
            {
                QFile::remove(m_pServer->serverName());
                m_pServer->listen(strServerName);
            }
        }
    }
}

void QSingleApplication::newLocalConnection()
{
    QLocalSocket *pSocket = m_pServer->nextPendingConnection();
    if (pSocket != NULL)
    {
        pSocket->waitForReadyRead(1000);

        QTextStream in(pSocket);
        QString strValue;
        in >> strValue;
        qDebug() << QString("The value is: %1").arg(strValue);

        delete pSocket;
        pSocket = NULL;
    }
}

bool QSingleApplication::isRunning()
{
    return m_bRunning;
}

使用方式

int main(int argc, char **argv)
{
    QSingleApplication app(argc,argv);
    if (app.isRunning())
    {
        QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
        exit(0);
    }

    MainWindow window;
    window.show();

    return app.exec();
}

QtSingleApplication

QSingleApplication位于qt-solution里面,并不包含在Qt库中,遵循 LGPL 协议。

文档、源码、示例见:QtSingleApplication

任务列表

运行程序时,遍历任务列表,查看是当前所有运行中的进程,如果当前进程位置在映射路径中可以找到,则说明程序已经运行,否则,未运行。

更多参考

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10073 0
Qt之运行一个实例进程
简述 发布程序的时候,我们往往会遇到这种情况: 只需要用户运行一个实例进程 用户可以同时运行多个实例进程 一个实例进程的软件有很多,例如:360、酷狗… 多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ… 下面我们来介绍下如何实现一个实例进程。 简述 QSharedMemory QLocalServer QtSing
735 0
python多进程通信实例分析
python多进程通信实例分析操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在。那么进程之间怎么进行通信?他们之间的关联是怎样的?实现原理是什么?本文就来借助Python简单的聊一下进程之间的通信?还是那句话,原理是相同的,希望能透过具体的例子来体会一下本质的东西。
2784 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13882 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
7365 0
+关注
潘志闻
互联网挖掘者
290
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载