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

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. Spring常用工具类(ApplicationContextAware、DisposableBean、InitializingBean)

    原创作品,出自 "晓风残月xj" 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj). 由于各种原因,可能存在诸多不 ...

  2. [SCSS] Loop Over Data with the SCSS @each Control Directive

    The SCSS @for directive is great when we know how many iterations are required and we only need 1 va ...

  3. JSON入门之二:org.json的基本用法 分类: C_OHTERS 2014-05-14 11:25 6001人阅读 评论(0) 收藏

    java中用于解释json的主流工具有org.json.json-lib与gson,本文介绍org.json的应用. 官方文档: http://www.json.org/java/ http://de ...

  4. Android中的消息机制:Handler消息传递机制 分类: H1_ANDROID 2013-10-27 22:54 1755人阅读 评论(0) 收藏

    参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...

  5. Android 为开发者准备的最佳 Android 函数库(2016 年版)

    本文是翻译自 CloudRAIL 的官方博客(https://cloudrail.com/best-android-libraries-for-developers/),本文中分享的 Android ...

  6. iOS过场动画调研笔记

    前言 因项目须要,近期一段时间都在调研iOS的过场动画.对于我来说这是一个之前没有太涉及的领域,所以有必要把调研的过程和自己的一些理解纪录下来 为什么要自己定义过场动画? 假设大家有关注Materia ...

  7. Android 添加常驻图标到状态栏

    / * * 如果没有从状态栏中删除ICON,且继续调用addIconToStatusbar,则不会有任何变化.如果将notification中的resId设置不同的图标,则会显示不同的图标 * / p ...

  8. Android系统编译环境初始化时Product产品的import-nodes过程

    从运行make -f config,mk文件開始,config,mk作为当前的makefile文件.将会被make解析,一般make解析Makefile文件流程首先是载入当中include的各种其它m ...

  9. OOA/OOD/OOP 转载

    OOA/OOD/OOP OOA Object-Oriented Analysis:面向对象分析方法 是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题.OOA与结构化分析有较 ...

  10. 谷歌AI中国中心成立,人工智能势不可挡?

    昨日,谷歌在上海举办了一年一度的Google中国开发者大会.在本届大会上,谷歌云首席科学家李飞飞宣布了一个重磅消息,即在北京将成立谷歌AI中国中心.对于这个即将成立的AI中心谷歌寄予厚望,希望与中国本 ...