我有一个在数据库上执行3异步make操作的代码。如果我运行3个异步操作,这段代码就会崩溃,但如果只有一个异步操作,就没有问题。如何在SQLite上组织多线程操作?我试过QMutex.lock,但没有用。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtConcurrent/QtConcurrentRun>
#include <database.h>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
Database *db0=new Database();
Database *db1=new Database();
Database *db2=new Database();
QString param0="Select LastUpdateDate From TableLastUpdateLog Where TableName='T1'";
QString param1="Select LastUpdateDate From TableLastUpdateLog Where TableName='T2'";
QString param2="Select LastUpdateDate From TableLastUpdateLog Where TableName='T3'";
QtConcurrent::run(db0,&Database::Select,param0);
QtConcurrent::run(db1,&Database::Select,param1);
QtConcurrent::run(db2,&Database::Select,param2);
return app.exec();
}
database.cpp
void Database::Select(QString query) {
m_db=QSqlDatabase::addDatabase("QSQLITE","myconn");
m_db.setDatabaseName("./mytask.db");
bool result=m_db.open();
if(result==false)
qDebug()<<"Failed";
else
{
qDebug()<<"Connection is Success";
m_qry=new QSqlQuery(m_db);
m_qry->exec("PRAGMA foreign_keys = ON;");
m_qry->exec("DSQLITE_THREADSAFE=2");
m_qry->prepare(query);
if(m_qry->exec()!=true)
{
qDebug()<<"Query Failed:"<<m_qry->lastError();
qDebug()<<m_qry->lastQuery();
}
else
{
QSqlRecord rec=m_qry->record();
while(m_qry->next())
{
qDebug()<<m_qry->value("LastUpdateDate").toDateTime();
}
}
}
m_db.close();
m_db.removeDatabase("myconn");
//mutex.unlock();
}
发布于 2016-06-13 08:30:20
您的代码会崩溃,因为您仍然是,使用相同的连接从每个线程访问数据库。在Qt连接中,由它们的名称标识(即传递给addDatabase
的值"myconn“)。
不仅Qt会行为不当,而且sqlite驱动程序也会出错。来自Qt文档
Warning: If you add a connection with the same name as an existing connection,
the new connection replaces the old one.
您的语句SQLITE_THREADSAFE=2
允许与没有两个线程试图使用同一个数据库连接。一样的多线程,但事实并非如此。
解决方案是为每个对象提供不同的连接名称。
https://stackoverflow.com/questions/37741279
复制相似问题