转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html

进程的互斥运行:CreateMutex函数实现只运行一个程序实例

  正常情况下,一个进程的运行一般是不会影响到其他正在运行的进程的。但是对于某些有特殊要求的如以独占方式使用串行口等硬件设备的程序就要求在其进程运行期间不允许其他试图使用此端口设备的程序运行的,而且此类程序通常也不允许运行同一个程序的多个实例。这就引出了进程互斥的问题。

  实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,如果没有,进程将成功创建并设置标识实例已经存在的标记。此后再创建进程时将会通过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。具体可以采取内存映射文件、有名事件量、有名互斥量以及全局共享变量等多种方法来实现。下面就分别对其中具有代表性的有名互斥量和全局共享变量这两种方法进行介绍:

// 创建互斥量
 HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");
 // 检查错误代码

// 如果程序已经存在并且正在运行
 if (GetLastError() == ERROR_ALREADY_EXISTS)

{
   // 如果已有互斥量存在则释放句柄并复位互斥量
  CloseHandle(m_hMutex);
  m_hMutex = NULL;
  // 程序退出
  return FALSE;
 }

  上面这段代码演示了有名互斥量在进程互斥中的用法。代码的核心是CreateMutex()对有名互斥量的创建。CreateMutex()函数可用来创建一个有名或无名的互斥量对象,其函数原型为:

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  BOOL bInitialOwner, // 初始化互斥对象的所有者
  LPCTSTR lpName // 指向互斥对象名的指针
  );

  如果函数成功执行,将返回一个互斥量对象的句柄。如果在CreateMutex()执行前已经存在有相同名字的互斥量,函数将返回这个已经存在互斥量的句柄,并且可以通过GetLastError()得到错误代码ERROR_ALREADY_EXIST。可见,通过对错误代码ERROR_ALREADY_EXIST的检测可以实现CreateMutex()对进程的互斥。

建立互斥体,用来同步。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。  
  参数  
  lpMutexAttributes    
  指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。     
  bInitialOwner 
  布尔类型,决定互斥体的创建者是否为拥有者  
  lpName    
  指向互斥体名字字符串的指针。互斥体可以有名字。  
  互斥体的好处是可以在进程间共享

将 CreateMutex 代码加到  ****App::InitInstance() 函数中即可实现只运行一个实例的效果。

以上文章转载自:我的程序员生涯 http://steveq.blog.sohu.com/71112121.html

通过上面文章我们知道:使用CreateMutex可以防止一个实例多次运行。

下面介绍如何实现当再次运行程序时如何激活已经运行的程序,比如此程序只是已被最小化。

方法如下:

 1 BOOL C**App::InitInstance()
 2 {
 3
 4  //创建进程互斥体Sample07
 5  m_hMutex = CreateMutex(NULL,TRUE,_T("Sample07"));
 6
 7  if (m_hMutex == NULL)
 8  {
 9   return FALSE;
10  }
11
12  //如果程序已经存在并且正在运行
13  if (GetLastError() == ERROR_ALREADY_EXISTS)
14  {
15
16   HWND hProgramWnd = ::FindWindow(NULL,L"Sample07");
17   if (hProgramWnd)
18   {
19    WINDOWPLACEMENT* pWndpl = NULL;
20
21    WINDOWPLACEMENT   wpm;
22    pWndpl =&wpm;
23    GetWindowPlacement(hProgramWnd,&wpm);
24    if (pWndpl)
25    {
26     //将运行的程序窗口还原成正常状态
27     pWndpl->showCmd = SW_SHOWNORMAL;
28     ::SetWindowPlacement(hProgramWnd,pWndpl);
29     SetWindowPos(hProgramWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
30     FlashWindow(hProgramWnd,TRUE);//任务栏图标闪烁
31    }
32
33   }
34   //关闭进程互斥体
35
36   CloseHandle(m_hMutex);
37   m_hMutex = NULL;
38   return FALSE;
39  }
40 }

VC 实现程序只运行一个实例,并激活已运行的程序相关推荐

  1. 限制程序只打开一个实例(转载)

    当我们在做一些管理平台类的程序(比如Windows的任务管理器)时,往往需要限制程序只能打开一个实例.解决这个问题的大致思路很简单,无非是在程序打开的时候判断一下是否有与自己相同的进程开着,如果有,则 ...

  2. [Winform]只允许运行一个exe,如果已运行则将窗口置前

    摘要 接着介绍项目中用到的一些方法,在winform中,打好包,有时并不允许运行多个客户端,要保证只有一个客户端运行.如果已经运行了,则弹出已运行的窗口,使其展示. 方法 判断是否有相同的进程 /// ...

  3. C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码

    2019独角兽企业重金招聘Python工程师标准>>> 我们开发WinFrom程序,很多时候都希望程序只有一个实例在运行,避免运行多个同样的程序,一是没有意义,二是容易出错.为了更便 ...

  4. 转:让程序只运行一个实例的四种方法

    先留着以后有用. 让程序只运行一个实例的四种方法 综述:让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建前,有窗口的程序在窗口创建前,检查系统中是否已经设置了某些特定标志了,如果 ...

  5. 让Java程序只运行一个实例

    一个程序可以在内存里面存在多个运行实例,比如,你可以打开多个微软的Word程序.但是,有些时候我们需要控制程序运行的实例只有一个,也就是说,该程序同一时刻在内存里面运行的只有一个实例.这样当这个程序在 ...

  6. C#程序只允许运行一个实例的解决方案

    最近在做winform的程序中,需要只能打开一个程序,如果已经存在,则激活该程序的窗口,并显示在最前端.在网上google了一哈,找到了很多的解决方案.这里我整理了3种方案,并经过了测试,现和朋友们分 ...

  7. 解决C#程序只允许运行一个实例的几种方法详解

    解决C#程序只允许运行一个实例的几种方法详解 参考文章: (1)解决C#程序只允许运行一个实例的几种方法详解 (2)https://www.cnblogs.com/randyzhuwei/p/5403 ...

  8. C# WinForm 判断程序是否已经在运行,且只允许运行一个实例

    static class Program {   /// <summary>   /// 应用程序的主入口点.   /// </summary>   [STAThread]   ...

  9. 只运行一个实例的方法

    在VC++ 中编程中,只运行一个实例的方法主要有两类: 1 遍历当前的所有窗口,查找相同的实例.为了便于查找,一般要事先设一个查找标志. 2 利用系统提供的互斥对象或信标,直接让系统抑制重复的实例. ...

  10. 只运行一个实例的写法

    有时我们需要只允许运行应用程序的一个实例,当进程启动时,如果发现应用程序的一个实例在运行,就自动停止运行.我们通常通过Mutex互斥体在Main函数中实现,通常的写法是: [STAThread] st ...

最新文章

  1. 北斗导航 | 完全自主研发国产高端三维激光雷达助力中国测绘技术发展
  2. 如何解压tar.xz文件
  3. 什么是闭合GOP和开放GOP?
  4. 使用这些HTTP标头保护您的Web应用程序
  5. Memcache分布式部署方案
  6. python里format有什么用_python format用法详解
  7. MotionEvent事件在onInterceptTouchEvent()、onTouchEvent()中的传递顺序
  8. HDOJ 3507 Print Article(DP + 斜率优化)
  9. 计算机维修的税收编码,维修服务在税收分类编码是什么?
  10. aliyun阿里云视频直播播放器代码
  11. Activiti6工作流入门初体验
  12. Git 使用 — Git下载与安装
  13. Spring Security | 轻松搞定认证授权~
  14. TopCoder比赛简介
  15. 更换钢丝绳,为何选择“国标锻造”钢丝绳夹(非铸件)
  16. Python学习笔记(六)Python基础_数据类型——字符串
  17. 计算机水平每分钟多少字,电脑打字每分钟打多少在一才算快啊? 一般拼音打字一分钟多少才算可以?...
  18. UVA10820欧拉函数求互质的对数
  19. Eclipse无法查看java源码
  20. 中国将强势反击,或暂停采购波音飞机,波音或因此受重击

热门文章

  1. MIMO-OTFS in High-Doppler Fading Channels:Signal Detection and Channel Estimation(4)
  2. 安卓实现tcp连接(安卓作为客户端,电脑作为服务端)
  3. windows安装MobaXterm
  4. java算术表达式求值-中缀表达式转后缀表达式
  5. 操作系统课设 Nachos 实验二:Nachos 的 Makefiles
  6. Codeforce 1800Difficulty Graphs 20 questions
  7. mysql 5个约束条件,Mysql入门第五课《外键约束》
  8. 在什么场合里你会用到消息队列?
  9. 基于Servlet+jsp的web计算器
  10. 万能的搜索--之DFS(二)