Qt 单例运行程序

QSystemSemaphore ss("iLavender", 1, QSystemSemaphore::Open);
ss.acquire();//获取临界区

QSharedMemory shared("iLavenderAssistant");//随便填个名字就行
if (!shared.create(1))
{
    ss.release();//UNIX会自动释放return 0;
}
ss.release();//释放临界区

//注意:这段代码只适用于windows!!! 不能放在代码段中如:{ ...}中和do{...}while(0);中,否则无效。可能是因为当里面变成了局部变量。

 

 

 

    // 使用共享内存,当第二个进程启动时,判断内存区数据是否建立,如有。则退出;
    // 这种方式有弊端,在程序发生崩溃时,未及时清除共享区数据,导致程序不能正常启动。

    // 信号量的意义,把操作共享内存的代码锁住。因为有可能同时点击2次APP, 防止并发  
    QSystemSemaphore sema("SingleApp Key", 1, QSystemSemaphore::Open);  
    sema.acquire();  

#ifdef Q_OS_LINUX  
    /*  Windows平台上不存在应用程序崩溃后,共享内存段还存在的情况 
     *  LINUX应用程序崩溃后,共享内存段不会自动销毁,则该程序再次运行会出问题 
     *  所以程序启动时先去检查是否有程序崩溃后还存留的共享内存段,如果有,先销毁,再创建 
     */  
    QSharedMemory mem("SingleApp");  
    // 尝试将进程附加到共享内存段  
    if (mem.attach()) 
    {  
        // 将共享内存与主进程分离, 如果此进程是附加到共享存储器段的最后一个进程,则系统释放共享存储器段,即销毁内容  
        mem.detach();  
    }  
#endif  
  
    /* 
     * 每个App打开的时候,获取一次共享内存。 
     * 如果获取失败,说明是第一个启动的APP,直接创建共享内存就好了。 
     * 如果获取成功,说明不是第一个,直接退出就好了。 
     * 保证App在系统里只能打开一个。 
     */  
    QSharedMemory unimem("SingleApp");  
    bool isRunning = false;  
    if (unimem.attach())  
        isRunning = true;   
    else 
    {  
        unimem.create(1);  
        isRunning = false;  
    }  
    sema.release();  
      
    if (isRunning)
    {  
        QMessageBox::warning(nullptr, "warning", "The app is running.");  
        exit(0);  
    }  

 转载于:Qt应用程序的单例化(程序只运行一个实例)_兜黎的博客-CSDN博客_qt单例程序

posted @ 2021-05-08 16:08  远方是什么样子  阅读(330)  评论(0编辑  收藏  举报