简介

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

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

代码实现

1. 互斥体实现方式

  1. //////////////////////////////////////////////////////////////////
  2. //
  3. // FileName : SingleRunByMutex.cpp
  4. // Creator : PeterZheng
  5. // Date : 2019/2/16 11:21
  6. // Comment : 互斥体实现进程单实例运行
  7. //
  8. //////////////////////////////////////////////////////////////////
  9. #include <iostream>
  10. #include <cstdio>
  11. #include <cstdlib>
  12. #include <Windows.h>
  13. using namespace std;
  14. // 使用互斥体保证单体运行
  15. BOOL IsAlreadyRun()
  16. {
  17. HANDLE hMutex = NULL;
  18. hMutex = CreateMutex(NULL, FALSE, "MYFLAG");
  19. if (hMutex != NULL)
  20. {
  21. if (ERROR_ALREADY_EXISTS == GetLastError())
  22. {
  23. ReleaseMutex(hMutex);
  24. return TRUE;
  25. }
  26. }
  27. return FALSE;
  28. }
  29. // 主函数
  30. int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
  31. {
  32. if (IsAlreadyRun())
  33. {
  34. MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
  35. }
  36. else
  37. {
  38. MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
  39. Sleep(30000);
  40. }
  41. ExitProcess(0);
  42. return 0;
  43. }

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

  1. //////////////////////////////////////////////////////////////////
  2. //
  3. // FileName : SingleRunByShareSeg.cpp
  4. // Creator : PeterZheng
  5. // Date : 2019/2/16 11:40
  6. // Comment : 通过共享全局变量的方式实现进程单实例运行
  7. //
  8. //////////////////////////////////////////////////////////////////
  9. #include <iostream>
  10. #include <cstdio>
  11. #include <cstdlib>
  12. #include <Windows.h>
  13. using namespace std;
  14. // 创建共享内存段
  15. #pragma data_seg("sharedata")
  16. DWORD dwFlagId = 0xEE;
  17. #pragma data_seg()
  18. #pragma comment(linker, "/SECTION:sharedata,RWS")
  19. // 使用共享内存段保证单体运行
  20. BOOL IsAlreadyRun()
  21. {
  22. if (dwFlagId == 0xEF)
  23. {
  24. return TRUE;
  25. }
  26. return FALSE;
  27. }
  28. // 主函数
  29. int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
  30. {
  31. if (IsAlreadyRun())
  32. {
  33. MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
  34. }
  35. else
  36. {
  37. MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
  38. dwFlagId = 0xEF;
  39. Sleep(30000);
  40. }
  41. ExitProcess(0);
  42. return 0;
  43. }

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. 区块链--Ubuntu上搭建以太坊私有链

    1.搭建私链所需环境 操作系统:ubuntu16.04,开虚拟机的话要至少4G,否则会影响测试挖矿时的速度 软件: geth客户端 Mist和Ethereum Wallet:https://githu ...

  2. paramiko之ssh登录,执行cmd,下载文件

    一.paramiko远程登录及执行命令 1.1:exec_command(cmd)远程执行命令 client = paramiko.SSHClient() client.set_missing_hos ...

  3. 再也不用被this苦恼了

    前端编程对于this再熟悉不过了,今日来个老调重弹温故知新,肯定有很多大佬已经完全吃透了this原理,敬请出门左拐.对于理解this似懂非懂的同学可以借鉴一波 1.this描述 this指的是当前执行 ...

  4. Python系列:三、流程控制循环语句--技术流ken

    Python条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和非 ...

  5. 部署vmware-vcsa 6.5

    介绍一下vcsa vsphere的两个最重要的组件是esxi和vcenter server,esxi是虚拟化主机管理软件,而vcenter server则是管理.组织多台esxi主机的管理中心. es ...

  6. 服务器文档下载zip格式

    刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Core.Utility;@{ s ...

  7. Android开发过程中的坑及解决方法收录(五)

    1. 导入依赖库出现错误 因为使用的sdk版本不同,使用下列代码强制使用最低版本,25.3.1就是我当前使用的版本号,根据自己的情况修改 configurations.all { resolution ...

  8. python基础学习(十一)公共方法

    Python内置函数 Python 包含了以下内置函数: 切片 切片 使用 索引值 来限定范围,从一个大的 字符串 中 切出 小的 字符串 列表 和 元组 都是 有序 的集合,都能够 通过索引值 获取 ...

  9. linux下的~/

    在linux里面,~/表示的是个人目录,例如你的账户是student,那么~/代表的是/home/student/

  10. Get与Post的主要区别

    这里附一篇自己的简短理解 get相对于post更不安全,虽然都可以加密 get的参数会显示在浏览器地址栏中,而post的参数不会显示在浏览器地址栏中: 使用post提交的页面在点击[刷新]按钮的时候浏 ...