• 4445阅读
  • 4回复

[提问]UI线程读 , 另一个线程写同一个sqlite [复制链接]

上一主题 下一主题
离线5free
 

只看楼主 倒序阅读 楼主  发表于: 2015-04-30
我有这样一个应用, UI线程,使用 QSqltablemodel 和 Qtableview 显示数据里面的数据。 在UI线程中中创建了另一个线程,用于不停采集数据,向数据库插入。

数据很小时,显示和插入就没有问题。但是当sqlite里数据量大了以后,只要UI线程一执行select(),另一个线程的的 query.exec() 就返回false里。请教破解方法!

我的代码类似这样:
在UI线程中创建一个数据库连接

  1. processDisplayDB =new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE","processDisplaydb"));
  2.     processDisplayDB->setDatabaseName("databases/ProductionData.s3db");
  3.     if(!processDisplayDB->open()){
  4.         qDebug()<<"Could not open file!"<<endl;
  5.         return;
  6.     }else{
  7.          qDebug()<<"Open file: "<<processDisplayDB->databaseName()<<" sucessfully!"<<endl;
  8.     }
  9.     modelProcessDisplay = new QSqlTableModel(ui->tableViewProcessDisplay,*processDisplayDB);
  10.     modelProcessDisplay->setTable("processtable");
然后通过定时器周期触发刷新信号,
  1. connect(&cylicTimerProcessDisplay,&QTimer::timeout,this,&MainWindow::processDisplayUpdate_cylic);
通过刷新来更新tableview内容
  1. void MainWindow::processDisplayUpdate_cylic()
  2. {
  3.   modelProcessDisplay->select();
  4. }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
另外一个线程是,建了另外一个连接到同一个数据库
  1. processDB = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE","processDB"));
  2.     processDB->setDatabaseName("databases/ProductionData.s3db");
  3.     if(!processDB->open()){
  4.         qDebug()<<"Could not open file!"<<endl;
  5.         return;
  6.     }else{
  7.          qDebug()<<"Open file: "<<processDB->databaseName()<<" sucessfully!"<<endl;
  8.     }
然后数据采集到以后,写入数据库

  1. QSqlQuery query(*processDB);
  2.     qDebug()<<"insert processtable prepare : "
  3.            <<query.prepare("INSERT INTO processtable(SerialNo) "
  4.                            "VALUES(:SerialNo)");
  5.     query.bindValue(":SerialNo",currentSerialNo);
  6.     qDebug()<<"insert processtable: "<<query.exec();




现在的问题是,当sqlite里数据量增大后, qDebug()<<"insert processtable: "<<query.exec(); 就执行不成功了。 经过检查,发现是 UI线程里 select() 引起的,但是不知道该怎么解决为好?  这个数据库是采集设备状态,肯定数据库不停增大的。

请大家帮帮我看看?谢谢





离线stlcours

只看该作者 1楼 发表于: 2015-04-30
对insert和select上锁,而且是同一把锁,相当于同一资源某一时刻只能一个人用。
离线5free

只看该作者 2楼 发表于: 2015-04-30
但是我不解的是,为什么数据库表数据少量的时候,就能正常插入呢?上锁能不能解决问题呢?


我也考虑过上锁,但是没用过qmutex,看文档是对一个代码,象我这样,在不同的线程,又是不同的动作,我就不会了,还请再指点指点
离线liulin188

只看该作者 3楼 发表于: 2015-05-01
1,上锁肯定能解决问题。
2,你数据量少时,每次写和读都非常快,那个访问时间太短了,所以基本上不可能冲突;你数据越多,写和读就越费时,冲突的可能性就越大。
你用10秒钟的时间闯红灯,和用10分钟的时间闯红灯,哪个出事可能性更大?

而且sqlite自身的库级锁的不强大,楼主必须在自己的代码里加锁。
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线zxwmail

只看该作者 4楼 发表于: 2015-05-04
请教:如果是多个读数组和一个写数组呢?
不考虑读的顺序的话,应该不用加锁了吧。
快速回复
限100 字节
 
上一个 下一个