最近在研究《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


        

同一个应用启动出两个java进程怎么办 同一个程序_同一个应用启动出两个java进程怎么办

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

同一个应用启动出两个java进程怎么办 同一个程序_linker_02

 运行结果:

     运行一个实例

同一个应用启动出两个java进程怎么办 同一个程序_windows_03

再运行一个实例的时候

同一个应用启动出两个java进程怎么办 同一个程序_attributes_04

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

   

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

    当我们运行一个程序的时候,内存首先要将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那就表示已经有一个实例在运行了。

     

同一个应用启动出两个java进程怎么办 同一个程序_attributes_05

同一个应用启动出两个java进程怎么办 同一个程序_linker_06

运行结果:

同一个应用启动出两个java进程怎么办 同一个程序_linker_07

再运行一个实例的时候

同一个应用启动出两个java进程怎么办 同一个程序_windows_08


总结:

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

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