保证一个程序在同一台PC中只运行一个实例的两种方法

    最近在研究《Windows核心编程》,留意到书中涉及到的两个知识点可以解决这个问题,觉得蛮有意思的,就记录下来,和大家分享下。

    第一种方法:采用线程同步中的互斥量内核对象

    互斥量(mutex)内核对象用来确保一个线程独占对一个资源的访问。 --------《Windows核心编程》

    互斥量对象包含一个使用计数,线程ID以及一个递归函数。              --------《Windows核心编程》

    涉及到的函数 

    HANDLE CreateMutex(

                    PSECURITY_ATTRIBUTES psa,

                    BOOL bInitialOwner,

                    PCTSTR pszName,

   );

  psa为安全属性,只要见到PSECURITY_ATTRIBUTES这个数据类型那就说明该函数涉及内核对象,所有的内核对象的创建函数都会有这个属性。

  bInitialOwner 如果该值为TRUE时,线程则立即拥有该互斥量,递归计数将被设为1,如果为FALSE,互斥量对象的线程ID和递归计数都将设置为0,互斥量处于触发状态。

  pszName指定互斥体对象的名字。

   BOOL ReleaseMutex(HANDLE hMutex);释放互斥量。

   CloseHandle(HANDLE) 清理句柄

代码示例:

        实验思路,先用VS2010创建一个win32程序,程序的主窗口以及消息循环向导程序已经创立完毕,我们只需在程序的入口处创建一个互斥量,再程序退出时释放互斥量就可以了。如果在创建过程中互斥量已经存在,则调用GetLastError()会返回ERROR_ALREADY_EXISTS

        

还有在程序结束前别忘记要释放互斥量以及CloseHandle();


 运行结果:

     运行一个实例


再运行一个实例的时候

出现这个提示,确定后程序直接退出。

   

 第二种方法:采用内存映射文件共享数据段

    当我们运行一个程序的时候,内存首先要将exe或DLL装载入内存中。.exe和DLL文件映像是由许多段组成,

每个标准的段名都以点号开始。例如。在编译程序的时候,编译器会将代码放在一个名叫.text的段中。再如

可执行文件的常用段

.bbs  未经初始化的数据

.CRT 只读的C运行时数据

.date 已初始化的数据

...............

除了这些标准的段外,Microsoft还允许我们创建自己的段。

#pragma data_seg("sectionname");

那么我们就可以创建一个自定义段, 包含一个Long变量

#pragma date_seg("Shared")

volatile LONG m_share_data=0;

#pragma date_seg("Shared")

如果将Shared这个段设置为共享的话,那么所有该程序的实例都会共享这个数据段,这样就可以通过m_sharea_date

来获得运行实例的数量。

#pragma comment(linker,"/SECTION:Shared,RWS");

R表示Read,W表示WRITE,E表示EXECUTE,S表示SHARED

代码示例:

     实验思路,创建一个共享数据段,在共享数据段里声明一个long的数据m_share_data,当第一个实例运行的时候将m_share_data加1 ,每次程序运行都会检测这个值,如果大于1那就表示已经有一个实例在运行了。

     


运行结果:


再运行一个实例的时候



总结:

         线程同步分为用户模式的线程同步以及内核模式的线程同步,互斥量只是内核模式线程同步中的一种,

而内存映射则是属于内存管理的范畴,这里提到的只是其中一个很小的知识点,也就是为大家更好的理解Windows编程起到一个抛砖引玉的作用吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值