One: use Qlocalsocket Mode: First when a new instance is started, an attempt is made to connect to the same local server, and if the connection fails, the first instance process is created and a local server creates. Otherwise, proceed to exit. (. Pro plus QT + network) voidmainwidget::initlocalconnection () { is_running = false; Qcoreapplication::setapplicationname ("LocalServer"); Qstringservername = Qcoreapplication::applicationname (); qlocalsocket socket; socket.connecttoserver (serverName); if (socket.waitforconnected) { is_running =true; & nbsp return; &NBSP} //is not connected to the server, create a server =new qlocalserver (this); connect (server, SIGNAL (Newconnection ()), This,slot (Newlocalconnection ()); if (Server->listen (serverName)) { //to prevent program crashes, residue process services, removal of & nbsp; if (server->servererror () = = Qabstractsocket::addressinuseerror &&qfile::exists ( Server->servername ())  &NBsp { qfile::remove (Server->servername ()); Server->listen (serverName); } }
Voidmainwidget::newlocalconnection () {qlocalsocket *socket =server->nextpendingconnection (); if (!socket) return; Socket->waitforreadyread (1000); Deletesocket; }
BOOL Mainwidget::isrunning () {returnis_running;}
Main.cpp: Mainwidget main_widget; if (!main_widget.isrunning ()) {main_widget.shownormal (); Main_widget.raise (); Main_widget.activatewindow (); Returnapp.exec (); }
1, create a qloaclsocket, connect to server 2, create a qlocalserver, and listen to connect 3, start the application, check how many connections, if at least one, means that open an application, then no longer open another.
two: Using Shared memory(1) qsharedmemory mode: Create a shared memory first, and then check that each application is ready to create a shared memory with the same unique_id, or, if not, that the instance is running. Qsharedmemory shared_memory; Shared_memory.setkey (unique_id); if (Shared_memory.attach ()) {return0;} if (Shared_memory.create (1)) {Mainwidget main_widget; Main_widget.shownormal (); Main_widget.raise (); Main_widget.activatewindow (); Returnapp.exec (); }
Qsharedmemory implementation of a single program run, when the running environment is UNIX, and the program unfortunately crashes, can cause shared memory can not be freed, so can not rerun the program. Exit cannot be used, and qapp->quit () is required.
Test can be used:
#ps-ef | grep test to find the program process number (if 6919)
#ipcs-M-p view shared memory for a process
#ipcs-M-p | grep 6919 If the program is interrupted unexpectedly, you can query that the shared memory still exists and read the Shmid number (first line ID)
#ipcrm-M 15826976 to remove shared memory
Reference Chart:
Ca
If you do not know the process number of the process, you can only infer the original process number based on the new process number, and then delete the shared memory that is left.
(2) Qsystemsemaphore//Ensure only run once Qsystemsemaphore semaphore ("Programkey", 1, Qsystemsemaphore::open); Semaphore.acquire (); Operation of shared memory in critical section sharedmemory qsharedmemory memory ("program")//Global object name if (!memory.create (1))//If global object exists prompt to exit {Qmessagebox :: Information (0, "Tip", "program Hasbeen running!"); Semaphore.release (); Return0; } semaphore.release ();
Third: Using Qtsingleapplication
Official release of the source code, direct download can be used. As for the first two ways, it can be problematic if the program collapses memory without releasing it under UNIX. Note Qtsingleapplication will generate a lock file in the/tmp directory, and if you change/tmp to read-only, you will not be able to run the program.
Qsingleapplication is located inside the qt-solution and is not included in the QT library, following the LGPL protocol. Reference github:https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication.
Reference: Qt-single App instance:http://berenger.eu/blog/c-qt-singleapplication-single-app-instance/and replacement of Qsingleapplication for Qt5:https://github.com/itay-grudev/singleapplication.
Four, network code, write a Qsingleapplication class, to implement the QT program of the single case (reference)
Scenario One: Use QT Qsharedmemory,qlocalserver and Qlocalsocket implementations (but add QT + network to your. Pro)
//"Single_application.h" #ifndef single_application_h #define SINGLE_APPLICATION_H #include <qapplication > #include <QSharedMemory> #include <QLocalServer> class singleapplication:public qapplication {Q_OBJEC
T public:singleapplication (int &argc, char *argv[], const QString uniquekey);
BOOL IsRunning ();
BOOL SendMessage (const QString &message);
Public slots:void receivemessage ();
Signals:void messageavailable (QString message);
Private:bool _isrunning;
QString _uniquekey;
Qsharedmemory sharedmemory;
Qlocalserver *localserver;
static const int timeout = 1000;
}; #endif//Single_application_h
"Single_application.cpp" #include <QLocalSocket> #include "single_application.h" Singleapplication:: singleapplication (int &argc, char *argv[], const QString uniquekey): Qapplication (argc, argv), _uniquekey (UniqueKey
) {Sharedmemory.setkey (_uniquekey);
if (Sharedmemory.attach ()) _isrunning = true;
else {_isrunning = false;
Create shared memory.
if (!sharedmemory.create (1)) {Qdebug ("Unable to create a single instance.");
Return
The//create local server and listen to incomming messages from the other instances.
LocalServer = new Qlocalserver (this);
Connect (LocalServer, SIGNAL (Newconnection ()), this, SLOT (ReceiveMessage ()));
Localserver->listen (_uniquekey);
}//Public slots.
void Singleapplication::receivemessage () {Qlocalsocket *localsocket = localserver->nextpendingconnection ();
if (!localsocket->waitforreadyread (timeout)) {Qdebug (Localsocket->errorstring (). ToLatin1 ());
Return } Qbytearray ByteArray = LocalsockeT->readall ();
QString message = Qstring::fromutf8 (Bytearray.constdata ());
Emit messageavailable (message);
Localsocket->disconnectfromserver ();
}//Public functions.
BOOL Singleapplication::isrunning () {return _isrunning;}
BOOL Singleapplication::sendmessage (const QString &message) {if (!_isrunning) return false;
Qlocalsocket Localsocket (this);
Localsocket.connecttoserver (_uniquekey, qiodevice::writeonly);
if (!localsocket.waitforconnected (timeout)) {Qdebug (Localsocket.errorstring (). ToLatin1 ());
return false;
} localsocket.write (Message.toutf8 ());
if (!localsocket.waitforbyteswritten (timeout)) {Qdebug (Localsocket.errorstring (). ToLatin1 ());
return false;
} localsocket.disconnectfromserver ();
return true;
Scenario Two: Use Qt qsharedmemory, and qtimert implementation, no other translation, or directly to the code bar:
"Single_application.h"
#ifndef single_application_h
#define Single_application_h
#include < qapplication>
#include <QSharedMemory>
class Singleapplication:public qapplication
{
q_ OBJECT public
:
singleapplication (int &argc, char *argv[], const QString uniquekey);
BOOL IsRunning ();
BOOL SendMessage (const QString &message);
Public slots:
void Checkformessage ();
Signals:
void messageavailable (QString message);
Private:
bool _isrunning;
Qsharedmemory sharedmemory;
};
#endif//Single_application_h
"Single_application.cpp" #include <QTimer> #include <QByteArray> #include "single_application.h" singleapplication::singleapplication (int &argc, char *argv[], const QString uniquekey): Qapplication (argc, argv) {s
Haredmemory.setkey (UniqueKey);
if (Sharedmemory.attach ()) _isrunning = true;
else {_isrunning = false;
Attach data to shared memory. Qbytearray ByteArray ("0");
The ' default value to ' Note ' No ' is available.
if (!sharedmemory.create (Bytearray.size ())) {Qdebug ("Unable to create single instance.");
Return
} sharedmemory.lock ();
Char *to = (char*) sharedmemory.data ();
const char *from = Bytearray.data ();
memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));
Sharedmemory.unlock ();
Start checking for messages of the other instances.
Qtimer *timer = new Qtimer (this);
Connect (timer, SIGNAL (timeout ()), this, SLOT (Checkformessage ()));
Timer->start (1000);
}//Public slots. void SingLeapplication::checkformessage () {sharedmemory.lock ();
Qbytearray ByteArray = Qbytearray ((char*) Sharedmemory.constdata (), sharedmemory.size ());
Sharedmemory.unlock ();
if (bytearray.left (1) = = "0") return;
Bytearray.remove (0, 1);
QString message = Qstring::fromutf8 (Bytearray.constdata ());
Emit messageavailable (message);
Remove message from shared memory.
ByteArray = "0";
Sharedmemory.lock ();
Char *to = (char*) sharedmemory.data ();
const char *from = Bytearray.data ();
memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));
Sharedmemory.unlock ();
}//Public functions.
BOOL Singleapplication::isrunning () {return _isrunning;}
BOOL Singleapplication::sendmessage (const QString &message) {if (!_isrunning) return false;
Qbytearray ByteArray ("1");
Bytearray.append (Message.toutf8 ()); Bytearray.append ('/0 ');
< should as Char here, not a string!
Sharedmemory.lock ();
Char *to = (char*) sharedmemory.data (); const char *from = Bytearray.daTa ();
memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));
Sharedmemory.unlock ();
return true;
}
Use:
"Main.cpp"
#include "single_application.h"
int main (int argc, char *argv[])
{
singleapplication App (argc, argv, "some unique key string");
if (app.isrunning ())
{
app.sendmessage ("message from other instance.");
return 0;
}
MainWindow *mainwindow = new MainWindow ();
Connect message queue to the main window.
Qobject::connect (&app, SIGNAL (messageavailable (QString)), MainWindow, SLOT (ReceiveMessage (QString)));
Show MainWindow.
Mainwindow->show ();
return app.exec ();
}