简介

在我们编写程序的时候,经常会注意到的一个问题就是如何能够让程序只运行一个实例,确保不会让同一个程序多次运行,从而产生诸多相同进程,给我们的带来不便呢?那么常用的有以下四种方法,第一种方法是通过扫描进程列表比对进程名来检测,第二种方法是通过枚举程序窗口的方式,第三种方法是采用共享全局变量来实现,第四种方法是通过创建互斥体来实现。

那么在这些方法中,第一种和第二种方法是有缺陷的,扫描进程列表比对进程名容易对相同进程名字的不同程序产生误报,枚举窗口不适用于无窗口程序且与扫描进程列表的方法也有相同的缺陷。所以本文笔者为大家介绍第三种方法与第四种方法的具体实现。

代码实现

1. 互斥体实现方式

//////////////////////////////////////////////////////////////////
//
// FileName : SingleRunByMutex.cpp
// Creator : PeterZheng
// Date : 2019/2/16 11:21
// Comment : 互斥体实现进程单实例运行
//
////////////////////////////////////////////////////////////////// #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h> using namespace std; // 使用互斥体保证单体运行
BOOL IsAlreadyRun()
{
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, "MYFLAG");
if (hMutex != NULL)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
ReleaseMutex(hMutex);
return TRUE;
}
}
return FALSE;
} // 主函数
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
if (IsAlreadyRun())
{
MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
}
else
{
MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
Sleep(30000);
}
ExitProcess(0);
return 0;
}

2. 共享全局变量实现方式

//////////////////////////////////////////////////////////////////
//
// FileName : SingleRunByShareSeg.cpp
// Creator : PeterZheng
// Date : 2019/2/16 11:40
// Comment : 通过共享全局变量的方式实现进程单实例运行
//
////////////////////////////////////////////////////////////////// #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h> using namespace std; // 创建共享内存段
#pragma data_seg("sharedata")
DWORD dwFlagId = 0xEE;
#pragma data_seg()
#pragma comment(linker, "/SECTION:sharedata,RWS") // 使用共享内存段保证单体运行
BOOL IsAlreadyRun()
{
if (dwFlagId == 0xEF)
{
return TRUE;
}
return FALSE;
} // 主函数
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
if (IsAlreadyRun())
{
MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
}
else
{
MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
dwFlagId = 0xEF;
Sleep(30000);
}
ExitProcess(0);
return 0;
}

C++实现程序单实例运行的两种方式的更多相关文章

  1. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  2. Qt实现应用程序单实例运行--LocalServer方式

    使Qt应用程序能够单实例运行的典型实现方法是使用共享内存实现.该方法实现简单,代码简洁. 但有一个致命缺陷:共享内存(QSharedMemory)实现的单程序运行,当运行环境是UNIX时,并且程序不幸 ...

  3. DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法

    原文:DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...

  4. iOS:创建单例对象的两种方式

    单例模式:创建单例对象的两种方式 方式一:iOS4版本之前      static SingleClassManager *singleManager = nil;      +(SingleClas ...

  5. c#设计应用程序单实例运行

    利用WindowsFormsApplicationBase的IsSingleInstance来控制应用程序只能单实例运行. [DllImport("user32.dll", Ent ...

  6. Java中 单例(Singleton)的两种方式

    第一种(饿汉式单例模式):在声明变量时实例化 public class Singleton { //静态初始化自动实例化 private static Singleton instance = new ...

  7. 浏览器原生 form 表单POST 数据的两种方式

    我们在提交表单的时候,form表单参数中会有一个enctype的参数.enctype指定了HTTP请求的Content-Type. 常用有两种:application/x-www-form-urlen ...

  8. linux保证程序单实例运行

    static int proc_detect(const char *procname){ char filename[100] = {0}; sprintf(filename, "%s/% ...

  9. web项目嵌入Jetty运行的两种方式(Jetty插件和自制Jetty服务器)

    在开发Java web项目时候,可以在项目中嵌入Jetty服务的方式来运行web程序. 由于最近开发web项目,自己使用的是比较旧的eclipse不支持导入tomcat来运行项目,于是就学习了下使用项 ...

随机推荐

  1. 配置 FATFS 支持长文件名

    FATFS 版本:Nov 09 14 R0.10c 在 FATFS 已经移植好的基础上,首先打开 ffconf.h 配置文件,找到如下图配置项: 可以将此值从 0 改为 1 使用 static wor ...

  2. SpringCloud学习(一):微服务简介

    一.前情概要 1.单体架构是什么 1).一个归档包包含了应用所有功能的应用程序, 我们通常称之为单体应用. 2).架构单体应用的架构风格, 我们称之为单体架构, 这是一种比较传统的架构风格. 2.单体 ...

  3. python安装第三方库的最简单方式

    一.准备工作 (只做一次准备工作,以后都会很方便) 1. 安装pip (1)下载pip到D:\download pip下载地址:https://pypi.python.org/pypi/pip#dow ...

  4. [转]Angular开发(十八)-路由的基本认识

    angular router https://angular.io/guide/router 本文转自:https://blog.csdn.net/kuangshp128/article/detail ...

  5. 第一册:lesson nineteen。

    原文:tired and thirsty. A:What's the matter,children? B:We are tired and thirsty. A:Sit down,here. Are ...

  6. __EF批量删除

    控制器: [HttpPost] public int Delete_All(string Id) { List<int> IDS = new List<int>();//创建l ...

  7. ASP.NET Core中使用Graylog记录日志

    以下基于.NET Core 2.1 定义GrayLog日志记录中间件: 中间件代码: public class GrayLogMiddleware { private readonly Request ...

  8. Element-UI 日期范围 date-picke

    实际项目应用案例: <el-form-item label="开始日期:" prop="StartDate"> <el-date-picker ...

  9. Josephu(约瑟夫)问题解析

    Josephu问题为: 设置编号为1,2,3,......n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1看是报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人出 ...

  10. 我为什么推荐Prettier来统一代码风格

    译者按: 关于代码风格,不同的人有不同的偏好,其实并没有什么绝对的对错.但是,有2条原则应该是对的: 少数服从多数:用工具统一风格. 原文: Why robots should format our ...