Qt运行一个实例进程-3种方式简介
来源:互联网 发布:python检测ip能否ping 编辑:程序博客网 时间:2024/06/07 23:03
文章转载于:http://blog.csdn.net/taiyang1987912/article/details/46989717
一:使用QLocalSocket
voidMainWidget::initLocalConnection()
{
}
voidMainWidget::newLocalConnection()
{
}
bool MainWidget::isRunning()
{
}
main.cpp中:
MainWidget main_widget;
if(!main_widget.isRunning())
{
}
1、创建一个QLoaclSocket,连接服务器
2、创建一个QLocalServer,并监听连接
3、启动应用程序之间,检查有多少个连接,如果至少有一个,意味着打开了一个应用程序,则不再打开另一个。
二:使用共享内存
(1)QSharedMemory
QSharedMemory shared_memory;
shared_memory.setKey(unique_id);
if(shared_memory.attach())
{
}
if(shared_memory.create(1))
{
}
QSharedMemory实现的单程序运行,当运行环境是UNIX时,并且程序不幸崩溃,会导致共享内存无法释放,从而无法重新运行程序!故退出不能使用exit,而需要使用qApp->quit()。
测试时可采用:
#ps -ef | grep test查出程序进程号(若为6919)
#ipcs -m -p查看进程的共享内存
#ipcs -m -p | grep 6919 若程序意外中断,可以查询到该共享内存仍然存在,读取shmid号(第一行id)
#ipcrm -m 15826976即可删除共享内存
参考图:
ca
如果无法知道进程的进程号,则只能根据新进程号推测原来的进程号,然后删除留下的共享内存。
QSharedMemory实现的单程序运行,当运行环境是UNIX时,并且程序不幸崩溃,会导致共享内存无法释放,从而无法重新运行程序!故退出不能使用exit,而需要使用qApp->quit()。
测试时可采用:
#ps -ef | grep test查出程序进程号(若为6919)
#ipcs -m -p查看进程的共享内存
#ipcs -m -p | grep 6919 若程序意外中断,可以查询到该共享内存仍然存在,读取shmid号(第一行id)
#ipcrm -m 15826976即可删除共享内存
参考图:
ca
如果无法知道进程的进程号,则只能根据新进程号推测原来的进程号,然后删除留下的共享内存。
(2)QSystemSemaphore
//确保只运行一次
QSystemSemaphore semaphore("ProgramKey",1, QSystemSemaphore::Open);
semaphore.acquire();
//在临界区操作共享内存SharedMemory
QSharedMemory memory("Program");//全局对象名
if(!memory.create(1)) //如果全局对象存在则提示退出
{
}
semaphore.release();
QSingleApplication位于qt-solution里面,并不包含在Qt库中,遵循 LGPL 协议。参考GitHub:https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication。
参考:Qt-Single App Instance:http://berenger.eu/blog/c-qt-singleapplication-single-app-instance/和Replacement of QSingleApplication for Qt5:https://github.com/itay-grudev/SingleApplication。
四、网络代码,写一个QSingleApplication类,来实现Qt程序的单例化(参考)
方案一:使用Qt中的QSharedMemory,QLocalServer和QLocalSocket实现(不过需要在你的.pro里加上QT += network)
三:使用QtSingleApplication
官方发布的有源码,直接下载就可以使用。至于前两种方式在unix下如果程序崩掉内存不释放会出问题。注意QtSingleApplication会在/tmp目录下生成lock文件,若把/tmp变为只读的,就无法运行程序了。
QSingleApplication位于qt-solution里面,并不包含在Qt库中,遵循 LGPL 协议。参考GitHub:https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication。
参考:Qt-Single App Instance:http://berenger.eu/blog/c-qt-singleapplication-single-app-instance/和Replacement of QSingleApplication for Qt5:https://github.com/itay-grudev/SingleApplication。
四、网络代码,写一个QSingleApplication类,来实现Qt程序的单例化(参考)
方案一:使用Qt中的QSharedMemory,QLocalServer和QLocalSocket实现(不过需要在你的.pro里加上QT += network)
// "single_application.h"#ifndef SINGLE_APPLICATION_H#define SINGLE_APPLICATION_H#include <QApplication>#include <QSharedMemory>#include <QLocalServer>class SingleApplication : public QApplication{Q_OBJECTpublic: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 single instance.");return;}// create local server and listen to incomming messages from 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;
方案二:使用Qt中的QSharedMemory,和QTimert实现,别的也没翻译,还是直接来代码吧:
// "single_application.h"#ifndef SINGLE_APPLICATION_H#define SINGLE_APPLICATION_H#include <QApplication>#include <QSharedMemory>class SingleApplication : public QApplication{Q_OBJECTpublic: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){sharedMemory.setKey(uniqueKey);if (sharedMemory.attach())_isRunning = true;else{_isRunning = false;// attach data to shared memory.QByteArray byteArray("0"); // default value to note that no message 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 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 be 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;}
使用:
// "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();}
0 0
- Qt运行一个实例进程-3种方式简介
- Qt运行一个实例进程-3种方式简介
- Qt运行一个实例进程
- Qt运行一个实例进程
- Qt运行一个实例进程
- Qt运行一个实例进程
- Qt之运行一个实例进程
- Qt之运行一个实例进程
- Qt之运行一个实例进程
- Qt只能运行一个实例的3种方法
- 进程只运行一个实例
- QT之QT只运行一个实例
- 使Qt 程序只能运行一个实例的3种方法
- 使Qt 程序只能运行一个实例的3种方法
- 使Qt程序只能运行一个实例的3种方法
- 使Qt程序只运行一个实例
- Qt程序只运行一个实例
- Qt程序只运行一个实例(转)
- Nim 网络编程
- Linux下使用mail命令发送邮件
- 判断游标是否结束
- 流式大数据处理的三种框架:Storm,Spark和Samza
- 两种方法在插入数据的时候,返回直增字段的主键
- Qt运行一个实例进程-3种方式简介
- iOS 原生地图定位
- 64位Windows下MySQL免安装版配置
- Android应用安全之Content Provider安全
- 关于span标签的宽度和高度设置
- 深入理解JVM : Java堆中对象创建、布局、访问全过程
- Android阅读源码从工具开始
- java mail实现Email的发送,完整代码
- oracle database recyclebin 速查文档