linux qt 只运行一个实例,Qt 只运行一个程序实例 -QLockFile -QSystemSemaphore 和 QSharedMemory...
Qt 只运行一个程序实例 -QLockFile -QSystemSemaphore 和 QSharedMemory前言每次只运行应用程序的一个实例可能是需要的,以限制内存泄露的问题,或者消除某些资源,文件,SQLite数据库等应用程序的两个实例之间的竞争问题。或者,原则上,应用程序只需要用户使用一个副本就行了。有两种方式可以用来解决这个问题:1、使用QLockFile当一个暂且文件被建立时,当应用
Qt 只运行一个程序实例 -QLockFile -QSystemSemaphore 和 QSharedMemory
前言
每次只运行应用程序的一个实例可能是需要的,以限制内存泄露的问题,或者消除某些资源,文件,SQLite数据库等应用程序的两个实例之间的竞争问题。或者,原则上,应用程序只需要用户使用一个副本就行了。
有两种方式可以用来解决这个问题:
1、使用QLockFile
当一个暂且文件被建立时,当应用程序关闭时消灭这个暂且文件。因此,在应用程序的第二个实例启动时检查该文件是否已经建立了一个打开的应用程序实例,若是这个文件存在那么第二个就可以不启动了。
2、使用QSystemSemaphore和QSharedMemory
这种通过建立一个共享内存段,并实验将其毗邻到具有唯一标识符的现有段。若是毗邻实验乐成,则解释应用程序的一个实例已经建立。因此,我们通知用户并关闭应用程序。若是毗邻实验不乐成,那么我们为应用程序选择建立这个内存段并运行第一个实例。
QLockFile
在应用程序启动时代,建立一个暂且“锁定文件”,若是实验建立锁定文件不乐成,则程序解释已经打开应用程序的一个实例,通知用户并关闭当前未启动的实例。
测试程序:
int main(int argc, char *argv[]) { QApplication a(argc, argv); // 本测试程序id取名为SingleAppTest QString path = QDir::temp().absoluteFilePath("SingleAppTest.lock"); // path = C:/Users/yu/AppData/Local/Temp/SingleAppTest.lock QLockFile lockFile(path); bool isLock = lockFile.isLocked(); // bool QLockFile::tryLock(int timeout = 0) // tryLock实验建立锁定文件。此函数若是获得锁,则返回true; 否则返回false。 // 若是另一个历程(或另一个线程)已经建立了锁文件,则此函数将最多守候timeout毫秒 if (!lockFile.tryLock(100)) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("The application is already running.\n" "Allowed to run only one instance of the application."); msgBox.exec(); return 1; } SingleAppTest w; w.setFixedSize(250, 150); w.show(); return a.exec(); }
效果:

使用QSystemSemaphore 和 QSharedMemory
在上面的例子中,通过限制Qt应用程序运行实例的数目,给出了一个简朴而利便的解决方案。
然则,在涉及用户权限方面场景时可能会有一些瑕玷。你想为整个盘算机运行一个单个实例,而且多用户可以运行它,那么用QLockFile就提供不了这个能力了。
QSharedMemory则相反,在盘算机上事情的同时,所有用户共享。因此,若是你的任何用户先运行程序,后者将无法运行它。然则在这种情形下,有需要思量差别平台共享内存的差异。
在Windows的情形下,共享内存将在程序正常完成时释放,并在突发情形下也能接纳。在Linux/UNIX的情形下发生突发情形时溃逃后内存将无法释放。
在下面的代码中,信号量用于在同时启动统一应用程序的多个实例的情形下解决竞争问题。
信号量由计数器建立,其最大数目为1.
当引发信号量时,应用程序的所有其他实例不再访问共享内存,因此一个实例完全拥有资源。此实例通过存在带有与此应用程序匹配的标识符的共享内存段来检查应用程序的另一个运行实例。该实例乐成启动并建立共享内存段,以防它找不到关于该应用程序的另一个实例的信息。之后,信号量被抛弃,允许应用程序的其他实例实验启动。
int main(int argc, char *argv[]) { QApplication a(argc, argv); // 建立信号量 QSystemSemaphore semaphore("SingleAppTest2Semaphore", 1); // 启用信号量,克制其他实例通过共享内存一起事情 semaphore.acquire(); #ifndef Q_OS_WIN32 // 在linux / unix 程序异常竣事共享内存不会接纳 // 在这里需要提供释放内存的接口,就是在程序运行的时刻若是有这段内存 先消灭掉 QSharedMemory nix_fix_shared_memory("SingleAppTest2"); if (nix_fix_shared_memory.attach()) { nix_fix_shared_memory.detach(); } #endif // 建立一个共享内存 “SingleAppTest2”示意一段内存的标识key 可作为唯一程序的标识 QSharedMemory sharedMemory("SingleAppTest2"); // 测试是否已经运行 bool isRunning = false; // 试图将共享内存的副本附加到现有的段中。 if (sharedMemory.attach()) { // 若是乐成,则确定已经存在运行实例 isRunning = true; } else { // 否则申请一字节内存 sharedMemory.create(1); // 确定不存在运行实例 isRunning = false; } semaphore.release(); // 若是您已经运行了应用程序的一个实例,那么我们将通知用户。 if (isRunning) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("The application is already running.\n" "Allowed to run only one instance of the application."); msgBox.exec(); return 1; } SingleAppTest2 w; w.setFixedSize(250, 150); w.show(); return a.exec(); }
运行效果:

程序源码
https://github.com/lesliefish/Qt/tree/master/Project/QtGuiApplication/SingleAppTest https://github.com/lesliefish/Qt/tree/master/Project/QtGuiApplication/SingleAppTest2
原文参考:
https://evileg.com/ru/post/147/
============= End
原文链接:https://www.cnblogs.com/lsgxeva/p/12826580.html
本站声明:网站内容泉源于网络,若有侵权,请联系我们,我们将及时处理。
更多推荐

所有评论(0)