【发布时间】:2017-11-16 05:34:23
【问题描述】:
我有一个 Qt 应用程序,它有一个 DatabaseService 单例,只有一个 QSqlDatabase 实例,许多线程应该使用这个 QSqlDatabase 实例,当某些线程使用 QSqlDatabase 实例时,互斥锁被锁定。但我知道这不是这项任务的最佳模式。
我应该在这里使用某种数据库连接池还是类似的东西?以及如何在 Qt 中实现它?
请提供一些例子。
UPD:
其实例已经拥有自己的线程的类,该类将有多个实例:
.cpp:
//...
QFuture<QMap<QString, QString>> future = QtConcurrent::run(DatabaseService::executeQuery, sqlCommand);
future.waitForFinished();
//...
数据库服务:
.h:
class DatabaseService
{
public:
//...
static QMap<QString, QString> executeQuery(QString command);
private:
static QThreadStorage<QSqlDatabase> mDatabasePool;
static QSqlDatabase getDatabase();
};
.cpp:
//...
QThreadStorage<QSqlDatabase> DatabaseService::mDatabasePool;
QSqlDatabase DatabaseService::getDatabase()
{
if(DatabaseService::mDatabasePool.hasLocalData()) {
return DatabaseService::mDatabasePool.localData();
} else {
auto database = QSqlDatabase::addDatabase("QPSQL", QUuid::createUuid().toString());
database.setHostName("hostName");
database.setDatabaseName("databaseName");
database.setUserName("user");
database.setPassword("password");
DatabaseService::mDatabasePool.setLocalData(database);
return database;
}
}
QMap<QString,QString> DatabaseService::executeQuery(QString command){
QSqlQuery query (DatabaseService::getDatabase());
query.exec(command);
//...
return result;
}
//...
UPD 2:
main.cpp:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
server.listen(QHostAddress::Any, 1234);
return a.exec();
}
我的服务器.h:
class MyServer : public QTcpServer
{
Q_OBJECT
explicit MyServer(QObject *parent = 0);
~MyServer();
protected:
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
signals:
void stopAll();
};
我的服务器.cpp:
MyServer::MyServer(QObject *parent) : QTcpServer(parent)
{
}
MyServer::~MyServer(){
emit stopAll();
}
void MyServer::incomingConnection(qintptr socketDescriptor){
QThread* clientThread = new QThread;
MyClient *client = new MyClient(socketDescriptor, this);
client->moveToThread(clientThread);
connect(clientThread, SIGNAL(started()), client, SLOT(process()));
connect(client, SIGNAL(finished()), clientThread, SLOT(quit()));
connect(this, SIGNAL(stopAll()), client, SLOT(stopFromServer()));
connect(client, SIGNAL(finished()), client, SLOT(deleteLater()));
connect(clientThread, SIGNAL(finished()), clientThread, SLOT(deleteLater()));
clientThread->start();
}
myclient.h:
class MyClient : public QObject
{
Q_OBJECT
public:
explicit MyClient(int socketDescriptor, MyServer *server);
~MyClient();
private:
QSslSocket* socket = NULL;
public slots:
void process();
}
myclient.cpp:
void MyClient::process(){
//typical connection things
connect(this->socket, SIGNAL(encrypted()), this, SLOT(ready()));
}
void MyClient::ready(){
connect(socket,SIGNAL(readyRead()),this, SLOT(newData()));
}
【问题讨论】:
标签: c++ multithreading qt