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

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. [Recompose] Transform Props using Recompose --mapProps

    Learn how to use the 'mapProps' higher-order component to modify an existing component’s API (its pr ...

  2. JavaScript中的一些细节 分类: C1_HTML/JS/JQUERY 2014-08-05 16:45 384人阅读 评论(0) 收藏

    1.设置id / class等属性 用 setAttribute 设置一些常规属性如 id ,className 的时候经常不起作用,只能用 object.id = value 这样来设置 news_ ...

  3. Java中String推断相等equals与==的差别以及StringBuilder的equals

    Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的"相等"有所不同,接下来进行分析,结论由程序进行验证 Str ...

  4. web网站如何实现兼容手机

    web网站如何实现兼容手机 一.总结 一句话总结:加上这句话即可:<meta name="viewport" content="width=device-width ...

  5. spring boot中servlet启动原理

    启动过程及原理 1 spring boot 应用启动运行run方法 StopWatch stopWatch = new StopWatch(); stopWatch.start(); Configur ...

  6. SQLServer重建索引

    Use [数据库名称]Go DECLARE @DBCCString NVARCHAR(1000)DECLARE @TableName VARCHAR(100)DECLARE Cur_Index CUR ...

  7. 【u028】数列的整除性

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式, ...

  8. J2EE学习篇之--JQuery技术具体解释

    前面我们解说了的J2EE的技术都是服务端的技术,以下我们来看一下前端的一些开发技术,这一篇我们来看一下jQuery技术 简单介绍: jQuery由美国人John Resig创建,至今已吸引了来自世界各 ...

  9. [Redux] Important things in Redux

    Root Smart component can be overloaded, divide 'smart' component wisely & using Provider. Proble ...

  10. Indy10 控件的使用(2)TidTCpServer组件学习

    以下来自英文原版帮助文件,文桓英语不好,翻译了老半天.有错误的地方见谅,别骂我. TIdTCPServer = class(TIdComponent) Description TIdTCPServer ...