一、
二、
#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(); }