gpt4 book ai didi

c++ - QSharedMemory::create() 问题

转载 作者:搜寻专家 更新时间:2023-10-31 01:42:32 25 4
gpt4 key购买 nike

我正在尝试编写一个只允许运行一个程序实例的SingleApplication 类。我正在使用 QSharedMemory

实现它

程序运行良好,除非我使用值为 "42" 的键。我做错了什么吗?这是未定义的行为吗?

main.cpp

int main(int argc, char *argv[])
{

//QApplication a(argc, argv);
SingleApplication a(argc, argv, "42"); //Does not work with '42'. Will work for any other value.



MainWindow w;
w.show();


return a.exec();
}

SingleApplication.h

class SingleApplication : public QApplication
{
Q_OBJECT

public:
SingleApplication(int &argc, char *argv[], const QString uniqueKey);

bool alreadyExists() const{ return bAlreadyExists; }

bool isMasterApp() const { return !alreadyExists(); }

bool sendMessage(const QString &message);

public slots:
//void checkForMessages();

signals:
//void messageAvailable(const QStringList& messages);

private:
bool bAlreadyExists;
QSharedMemory sharedMemory;

};

SingleApplication.cpp

SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv){

sharedMemory.setKey(uniqueKey);

//Create if one does not exist already
if(sharedMemory.create(5000))
{
qDebug() << "Created!";

bAlreadyExists = false;
}
else{
if(sharedMemory.error() == QSharedMemory::AlreadyExists){
qWarning() << "Program is already running!";
}
}
}

最佳答案

我建议您下一个解决方案。它已经过测试,但不支持在实例之间发送消息。它解决了您的解决方案的一些错误。因为仅仅测试内存是不够的。您需要保护共享内存的创建。

RunGuard.h

#ifndef RUNGUARD_H
#define RUNGUARD_H

#include <QObject>
#include <QSharedMemory>
#include <QSystemSemaphore>


class RunGuard
{

public:
RunGuard( const QString& key );
~RunGuard();

bool isAnotherRunning();
bool tryToRun();
void release();

private:
const QString key;
const QString memLockKey;
const QString sharedmemKey;

QSharedMemory sharedMem;
QSystemSemaphore memLock;

Q_DISABLE_COPY( RunGuard )
};


#endif // RUNGUARD_H

RunGuard.cpp

#include "RunGuard.h"

#include <QCryptographicHash>


namespace
{

QString generateKeyHash( const QString& key, const QString& salt )
{
QByteArray data;

data.append( key.toUtf8() );
data.append( salt.toUtf8() );
data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex();

return data;
}

}


RunGuard::RunGuard( const QString& key )
: key( key )
, memLockKey( generateKeyHash( key, "_memLockKey" ) )
, sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) )
, sharedMem( sharedmemKey )
, memLock( memLockKey, 1 )
{
QSharedMemory fix( sharedmemKey ); // Fix for *nix: http://habrahabr.ru/post/173281/
fix.attach();
}

RunGuard::~RunGuard()
{
release();
}

bool RunGuard::isAnotherRunning()
{
if ( sharedMem.isAttached() )
return false;

memLock.acquire();
const bool isRunning = sharedMem.attach();
if ( isRunning )
sharedMem.detach();
memLock.release();

return isRunning;
}

bool RunGuard::tryToRun()
{
if ( isAnotherRunning() ) // Extra check
return false;

memLock.acquire();
const bool result = sharedMem.create( sizeof( quint64 ) );
memLock.release();
if ( !result )
{
release();
return false;
}

return true;
}

void RunGuard::release()
{
memLock.acquire();
if ( sharedMem.isAttached() )
sharedMem.detach();
memLock.release();
}

关于c++ - QSharedMemory::create() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26704533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com