介绍
让程序实现单例模式,只能打开一次,这已经是一个老生常谈的问题了。
方法也有很多,比如说监听端口,文件锁。我这里介绍一个用共享内存的方法。
先上代码
代码部分
- 代码部分(.h文件):
namespace JQFoundation
{
bool singleApplication(const QString &flag);
bool singleApplicationExist(const QString &flag);
}
- 代码部分(.cpp文件):
#if !(defined Q_OS_IOS) && !(defined Q_OS_ANDROID) && !(defined Q_OS_WINPHONE)
bool JQFoundation::singleApplication(const QString &flag)
{
static QSharedMemory *shareMem = nullptr;
if (shareMem)
{
return true;
}
shareMem = new QSharedMemory( "JQFoundationSingleApplication_" + flag );
for ( auto count = 0; count < 2; ++count )
{
if (shareMem->attach( QSharedMemory::ReadOnly ))
{
shareMem->detach();
}
}
if ( shareMem->create( 1 ) )
{
return true;
}
return false;
}
#else
bool JQFoundation::singleApplication(const QString &)
{
return true;
}
#endif
#if !(defined Q_OS_IOS) && !(defined Q_OS_ANDROID) && !(defined Q_OS_WINPHONE)
bool JQFoundation::singleApplicationExist(const QString &flag)
{
QSharedMemory shareMem( "JQFoundationSingleApplication_" + flag );
for ( auto count = 0; count < 2; ++count )
{
if (shareMem.attach( QSharedMemory::ReadOnly ))
{
shareMem.detach();
}
}
if ( shareMem.create( 1 ) )
{
return false;
}
return true;
}
#else
bool JQFoundation::singleApplicationExist(const QString &)
{
return false;
}
#endif
接口
只有两个接口,使用都很简单,传入的参数就是一个标记字符串
- singleApplication
检查单例模式,并且上锁。返回true表示上锁成功,false表示失败。
- singleApplicationExist
检查单例模式,但不上锁。返回true表示已经有锁,false表示无锁。
使用
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if ( !JQFoundation::singleApplication( "myApplication" ) )
{
qDebug() << "Application already running";
return -1;
}
return a.exec();
}
注意
在移动平台上,共享内存不一定是可靠的,所以在移动平台上就用条件编译跳过了,毕竟移动平台上一般程序都已经是单例模式了。