c++ 让程序只启动一个实例



1. 用互斥(Mutex),Mutex本来是多线程同步用的,防止多个线程访问同一资源而引发冲突。用CreateMutex可以创建Mutex对象,实质上是一个kernel对象。    
在任何Win32程序(包括GDI和Console)的启动部分加上以下代码(Console程序的main函数、MFC程序的CWinApp派生类的InitInstance成员函数、RawSDK程序的WinMain函数):
  hMutex=CreateMutex(    
  NULL,//nosecurityattributes    
  FALSE,//initiallynotowned    
  "RunOnlyOneInstance"); //命名Mutex是全局对象    
                                          //在所有的process都可以访问到    
  if(hMutex==NULL||    
      ERROR_ALREADY_EXISTS==::GetLastError()) {   
      //程序第二次或以后运行时,会得到Mutex已经创建的错误    
      returnFALSE;    
  }

2.查找窗口,激活。  
  HWND   hOldWnd;  
  if((hOldWnd=::FindWindow(NULL,_T("志软个人信息管理")))!=NULL)  
  {   
      ShowWindow(hOldWnd,SW_RESTORE | SW_SHOWNORMAL);  
      SetForegroundWindow(hOldWnd);  
      return   FALSE;
  }

3.内存映射文件MutexRuning为程序名
 
  初始化阶段:  
  InitInstance中:
  HANDLE   hMap=CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,128,  
                                                              "MutexRuning");  
  if(hMap==NULL)  
  {   
      AfxMessageBox("创建内存映射文件失败",MB_OK|MB_ICONSTOP);   
      return   FALSE;  
  }  
  else   if(GetLasError()==ERROR_ALREADY_EXISTS)  
  {   
      LPVOID   lpMem=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);   
      CString   str=(char   *)lpMem;   
      UnmapViewOfile(lpMem);   
      CloseHandle(hMap);   
    
      AfxMessageBox(str,MB_OK|MB_ICONSTOP);   
      return   FALSE;  
  }  
  else  
  {   
      //是第一次运行   
      LPVOID   lpMem=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);   
      //程序运行描述信息   
      strcpy((char*)lpMem, "xxxx正在运行!");   
      UnmapViewOfFile(lpMem);  
  }

4.使用原子    
  BOOL   CMainApp::InitInstance()  
  { 
      .....   
      if(GlobalFindAtom("AdBreaker"))     //找原子   
          return   false;   
      ATOM   GlobalAtom=GlobalAddAtom("AdBreaker");   //添加原子   
      CAdBreakerDlg   dlg;   
      m_pMainWnd   =   &dlg;   
      int   nResponse   =   dlg.DoModal();   
      .....           
      GlobalDeleteAtom(GlobalAtom);   
      return   FALSE;  
  }

要限制自己编写的 C++ 程序只能同时启动一个实例,您可以使用操作系统提供的进程间通信机制,如命名管道(named pipe)或者共享内存(shared memory)。通过这些机制,您可以在程序启动时检查是否已经有另一个实例正在运行,并采取相应的措施。 以下是一种使用命名管道的方法: 1. 在程序中创建一个命名管道,用于检查是否已经有实例在运行。可以使用 `mkfifo` 函数创建命名管道,例如: ```cpp #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> const char* PIPE_PATH = "/tmp/my_pipe"; int main() { // 创建命名管道 mkfifo(PIPE_PATH, 0666); // 检查是否已经有实例在运行 int pipefd = open(PIPE_PATH, O_RDONLY | O_NONBLOCK); if (pipefd == -1) { // 管道已经存在,说明有另一个实例在运行 // 执行相应的处理逻辑,比如退出程序或给出提示信息 return 0; } // 在这里执行您的程序的主要逻辑 // 关闭并删除命名管道 close(pipefd); unlink(PIPE_PATH); return 0; } ``` 2. 在程序启动时,尝试打开命名管道。如果打开失败,则说明已经有另一个实例在运行,您可以选择退出程序或者给出相应的提示信息。 请注意,命名管道的路径应该是唯一的,以避免与其他程序冲突。在上述示例中,我使用的是 `/tmp/my_pipe` 作为命名管道的路径,您可以根据需要进行修改。 这只是一种实现方式,您还可以考虑使用其他进程间通信机制来实现同样的目的。具体实现方式取决于您的操作系统和编程环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值