一、

二、

#ifndef RUNGUARD_H
#define RUNGUARD_H

#include <QObject>
#include <QSharedMemory>
#include <QSystemSemaphore>
class RunGuard
{

public:
    explicit RunGuard(const QString& key);
    ~RunGuard();

    bool isAnotherRunning();
    bool tryToRun();
    void release();

private:
    const QString key;
    const QString memLockKey;
    const QString sharedmemKey;

    QSharedMemory sharedMem;
    QSystemSemaphore memLock;

    Q_DISABLE_COPY( RunGuard )
};

#endif // RUNGUARD_H

 

#include "runguard.h"
#include <QCryptographicHash>
QString generateKeyHash( const QString& key, const QString& salt )
{
    QByteArray data;

    data.append( key.toUtf8() );
    data.append( salt.toUtf8() );
    data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex();

    return data;
}

RunGuard::RunGuard(const QString& key) :
    key( key ),
    memLockKey( generateKeyHash( key, "_memLockKey" ) ),
    sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) ),
    sharedMem( sharedmemKey ),
    memLock( memLockKey, 1 )
{

    memLock.acquire();
    {
        QSharedMemory fix( sharedmemKey );  
        fix.attach();
    }
    memLock.release();

}

RunGuard::~RunGuard()
{
    release();
}
bool RunGuard::isAnotherRunning()
{
    if ( sharedMem.isAttached() )
        return false;

    memLock.acquire();
    const bool isRunning = sharedMem.attach();
    if ( isRunning )
        sharedMem.detach();
    memLock.release();

    return isRunning;
}

bool RunGuard::tryToRun()
{
    if ( isAnotherRunning() )   // Extra check
        return false;

    memLock.acquire();
    const bool result = sharedMem.create( sizeof( quint64 ) );
    memLock.release();
    if ( !result )
    {
        release();
        return false;
    }

    return true;
}

void RunGuard::release()
{
    memLock.acquire();
    if ( sharedMem.isAttached() )
        sharedMem.detach();
    memLock.release();
}

 

#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
//#include "testwidget.h"
#include "runguard.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    RunGuard guard("QGroundControlRunGuardKey");
    if (!guard.tryToRun()) {
  
        QMessageBox::critical(nullptr, QObject::tr("Error"),
            QObject::tr("The program is already running. Please close the other instance and try again.")
        );
        return -1;
    }

    MainWindow w;
    w.show();

//    TestWidget w;
//    w.show();

    return a.exec();
}