QT+sqlite如何实现在不同线程同时执行“读”和“写”的操作
试验:建立两个线程test1和test2:在test1中写 在test2中读
实验一:
test1与test2使用同一个连接,同时进行写和读操作,程序崩溃
试验二:
分别在两个子线程建立连接,并执行SQL语句,源码如下:


结果程序崩溃
QT+sqlite如何实现在不同线程同时执行“读”和“写”的操作
试验:建立两个线程test1和test2:在test1中写 在test2中读
实验一:
test1与test2使用同一个连接,同时进行写和读操作,程序崩溃
试验二:
分别在两个子线程建立连接,并执行SQL语句,源码如下:


结果程序崩溃
上午好☀️☀️☀️️
本答案参考ChatGPT-3.5
在QT+sqlite中,要实现在不同线程同时执行“读”和“写”的操作,需要注意以下几点:
每个线程必须单独持有一个数据库连接
不同的线程之间不能直接共享连接对象,否则会出现线程同步问题
对于多线程操作sqlite库,需要对sqlite进行加锁操作,可以使用QReadWriteLock(读写锁)来实现。
解决方案如下:
// test1线程中创建连接
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");
db1.setDatabaseName("test.db");
if (!db1.open()) {
qDebug() << "can not open db1:" << db1.lastError();
return;
}
// test2线程中创建连接
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");
db2.setDatabaseName("test.db");
if (!db2.open()) {
qDebug() << "can not open db2:" << db2.lastError();
return;
}
// 多线程读取数据时,加上读锁
QReadLocker locker(&m_lock);
// 执行查询操作
QSqlQuery query(db);
query.exec("SELECT * FROM tablename");
while (query.next()) {
// 读取查询结果
}
// 多线程写入数据时,加上写锁
QWriteLocker locker(&m_lock);
// 执行插入操作
QSqlQuery query(db);
query.exec("INSERT INTO tablename (col1, col2) VALUES (val1, val2)");
// 关闭连接
db.close();
最终实现可以参考以下示例代码:
// test1线程中写入数据
void test1::run() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "connection1");
db.setDatabaseName("test.db");
if (!db.open()) {
qDebug() << "can not open db1:" << db.lastError();
return;
}
while (m_run) {
// 加上写锁,保证线程安全
QWriteLocker locker(&m_lock);
QSqlQuery query(db);
query.exec("INSERT INTO tablename (col1, col2) VALUES (val1, val2)");
// 睡眠1秒
QThread::msleep(1000);
}
db.close();
}
// test2线程中读取数据
void test2::run() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "connection2");
db.setDatabaseName("test.db");
if (!db.open()) {
qDebug() << "can not open db2:" << db.lastError();
return;
}
while (m_run) {
// 加上读锁,保证线程安全
QReadLocker locker(&m_lock);
QSqlQuery query(db);
query.exec("SELECT * FROM tablename");
while (query.next()) {
// 读取查询结果
}
// 睡眠1秒
QThread::msleep(1000);
}
db.close();
}