如果限制一个程序同时只能启动一个实例,有几个可以使用的库

main.cpp

限制程序同时只能启动一个实例只需要在 main() 函数里调用 if (!guard.tryToRun()) { return 0; } 即可。

1
2
3
4
5
6
7
8
9
10
11
12
#include "RunGuard.h"
 
int main(int argc, char *argv[]) {
RunGuard guard("9F0FFF1A-77A0-4EF0-87F4-5494CA8181C7");
 
if (!guard.tryToRun()) {
return 0;
}
 
QApplication a(argc, argv);
a.exec();
}

RunGuard.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef RUNGUARD_H
#define RUNGUARD_H
 
#include <QObject>
#include <QSharedMemory>
#include <QSystemSemaphore>
 
class RunGuard {
public:
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

RunGuard.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "RunGuard.h"
#include <QCryptographicHash>
 
namespace {
 
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 for *nix: http://habrahabr.ru/post/173281/
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();
}
 

http://www.qtdebug.com/qtbook-misc-single-application/

Single Application的更多相关文章

  1. How to: Use Both Entity Framework and XPO in a Single Application 如何:在单个应用程序中同时使用实体框架和 XPO

    This topic demonstrates how to create a simple XAF application that uses both the Entity Framework ( ...

  2. 4: 模块化应用程序开发 Modular Application Development Using Prism Library 5.0 for WPF (英汉对照版)

    A modular application is an application that is divided into a set of loosely coupled functional uni ...

  3. Concurrency and Application Design

    Concurrency and Application Design In the early days of computing, the maximum amount of work per un ...

  4. difference in physical path, root path, virutal path, relative virtual path, application path and aboslute path?

    http://stackoverflow.com/questions/13869817/difference-in-physical-path-root-path-virutal-path-relat ...

  5. Understanding IIS Bindings, Websites, Virtual Directories, and lastly Application Pools

    In a recent meeting, some folks on my team needed some guidance on load testing the Web application ...

  6. External Configuration Store Pattern 外部配置存储模式

    Move configuration information out of the application deployment package to a centralized location. ...

  7. 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY

    转载自: 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY Navicat Premium(数据库管理工具 ...

  8. Android Support Library

    title: Android Support Library tags: Support Library,支持库 grammar_cjkRuby: true --- DATE: 2016-5-13. ...

  9. Spring Boot文档阅读

    原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...

随机推荐

  1. CAP理论/AP架构/CP架构

      原文地址:https://blog.csdn.net/u013058742/article/details/83541905  简书里的文章:Spring Cloud Eureka简介及与Zook ...

  2. Spring boot(二) springboot + jsp

    官方不推荐JSP在Spring Boot中使用! 一.添加依赖 在pim.xml 里面添加以下 jsp依赖 <dependency> <groupId>org.springfr ...

  3. AE创建拓扑

    转自原文 AE创建拓扑 /// <summary> /// 创建拓朴 /// </summary> /// <param name="featureWorksp ...

  4. css选择器指定元素中第几个子元素

    tr td:nth-child(2){ background-color:gray; } 就是tr当中的td的第二个td的属性 tr:nth-child(2n+0){ background-color ...

  5. [Vue] Conditionally Render DOM Elements in Vue.js (v-if v-else v-show)

    You can use v-if and v-else to display content based on assertions on your data. Similarly, v-show c ...

  6. Spirng setter 注入简单

    1.      提供相应要注入的属性 //setter注入 public class Bean2 { private String name; private Integer age; // 提供要注 ...

  7. Angular.js回想+学习笔记(1)【ng-app和ng-model】

    Angular.js中index.html简单结构: <!doctype html> <html ng-app> <head> <script src=&qu ...

  8. Javascript中的DOM实现显示鼠标的空间位置

    为了显示鼠标相对于浏览器的位置(相对于屏幕和页面类似),我们能够利用click事件,获得关于鼠标单击的事件对象event.这个事件对象里的clientX和clientY包括了鼠标的位置信息,所以我突发 ...

  9. AJAX代码格式

    var request; //XMLHttpRequest的创建 function createRequest(url){ if(window.XMLHttpRequest){ request = n ...

  10. Eclipse使用技巧总结(六)

    四十.增量查找 Ctrl + J : Ctrl + Shift + J: 四十一.快速跳到某行 Ctrl + L 四十二.快速比较不同 Window-->Preference___查找quick ...