当前位置: 首页 > wzjs >正文

手机网站WordPress主题wordpress的菜单和页面

手机网站WordPress主题,wordpress的菜单和页面,怎么开店铺,哈尔滨网站推广公司Qt多线程访问同一个数据库源码分享(基于Sqlite实现) 一、实现难点线程安全问题死锁风险连接管理问题数据一致性性能瓶颈跨线程信号槽最佳实践建议 二、源码分享三、测试1、新建一个多线程类2、开启多线程插入数据 一、实现难点 多线程环境下多个线程同时…

Qt多线程访问同一个数据库源码分享(基于Sqlite实现)

  • 一、实现难点
    • 线程安全问题
    • 死锁风险
    • 连接管理问题
    • 数据一致性
    • 性能瓶颈
    • 跨线程信号槽
    • 最佳实践建议
  • 二、源码分享
  • 三、测试
    • 1、新建一个多线程类
    • 2、开启多线程插入数据

一、实现难点

多线程环境下多个线程同时访问同一个数据库会面临以下主要难点:

线程安全问题

数据库连接对象通常不是线程安全的,多个线程同时使用同一个连接会导致数据混乱或崩溃。每个线程需要独立的数据库连接。

死锁风险

多个线程同时执行事务操作时,如果锁定顺序不一致可能导致死锁。需要统一锁定顺序或使用超时机制。

连接管理问题

频繁创建和销毁连接会导致性能问题。可以使用连接池管理数据库连接。

数据一致性

多线程并发写入可能导致数据不一致。需要合理使用事务隔离级别和锁机制。

性能瓶颈

过多线程同时访问可能导致数据库成为性能瓶颈。需要限制最大并发线程数。

跨线程信号槽

Qt要求数据库对象必须在创建它的线程中使用。跨线程操作需要特别注意。

最佳实践建议

使用Qt的线程模块时,遵循以下原则可减少问题:

  • 每个线程使用独立的数据库连接
  • 合理使用事务和锁机制
  • 考虑使用连接池管理连接
  • 控制最大并发线程数
  • 避免跨线程传递数据库对象

商业数据库通常提供更好的多线程支持,SQLite等嵌入式数据库在多线程环境下需要特别注意。### 多线程数据库访问的难点

二、源码分享

由于多个线程访问同一个数据库所以用一个单例类来管理数据库,实现如下:

sqliteHelper.h

#ifndef SQLITEHELPER_H
#define SQLITEHELPER_H#include <QObject>
#include <QtSql>
#include <QString>
#include <QMutex>
#include <QMutexLocker>
#include <QWaitCondition>
#include <QQueue>
#include <QThread>class SqliteHelper
{
private:SqliteHelper();SqliteHelper(SqliteHelper& ) = delete;SqliteHelper operator=(const SqliteHelper &) = delete;
public:~SqliteHelper();static SqliteHelper *getInstance();static void changeDatabase(QString databaseName);bool lockExec(QString sql);QSqlDatabase *getDatabase();static void quit();
private:static void removeDatabases();
private:static QMutex mutexCreateSql,mutexUpdateSql;QString strConnName;static QString currentDatabaseName;static QHash<Qt::HANDLE, SqliteHelper*> databaseMap;//所有数据库链接,key: 线程ID,
};#endif // SQLITEHELPER_H

sqliteHelper.cpp

#include "sqliteHelper.h"QMutex SqliteHelper::mutexCreateSql;
QMutex SqliteHelper::mutexUpdateSql;
QHash<Qt::HANDLE, SqliteHelper*> SqliteHelper::databaseMap;
QString SqliteHelper::currentDatabaseName;SqliteHelper::SqliteHelper()
{mutexCreateSql.lock();Qt::HANDLE id = QThread::currentThreadId();strConnName = QString::number(*(unsigned int*)&id);QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", strConnName);database.setDatabaseName(currentDatabaseName);qDebug()<<"SQLiteHelper()  "<<strConnName;mutexCreateSql.unlock();
}SqliteHelper::~SqliteHelper()
{}SqliteHelper *SqliteHelper::getInstance()
{if(!databaseMap.contains(QThread::currentThreadId())) {databaseMap.insert(QThread::currentThreadId(), new SqliteHelper());}return databaseMap[QThread::currentThreadId()];
}void SqliteHelper::changeDatabase(QString databaseName)
{if(databaseName.isEmpty())return;SqliteHelper::removeDatabases();currentDatabaseName = databaseName;qDebug()<<databaseName;
}bool SqliteHelper::lockExec(QString sql)
{mutexUpdateSql.lock();QSqlDatabase sqlDb =QSqlDatabase::database(strConnName);if(!sqlDb.isOpen()){mutexCreateSql.lock();sqlDb.open();mutexCreateSql.unlock();}QSqlQuery sqlQuery(sqlDb);sqlQuery.prepare(sql);bool res = sqlQuery.exec();if(!res)qDebug()<<sqlQuery.lastError().text();sqlDb.close();mutexUpdateSql.unlock();return res;
}
QSqlDatabase *SqliteHelper::getDatabase()
{QSqlDatabase *sqlDb = new QSqlDatabase(QSqlDatabase::database(strConnName));if(!sqlDb->isOpen()){mutexCreateSql.lock();sqlDb->open();mutexCreateSql.unlock();}return sqlDb;
}void SqliteHelper::quit()
{currentDatabaseName = "";removeDatabases();
}void SqliteHelper::removeDatabases()
{qDebug()<<"SQLiteHelper::removeDatabases()";QList<Qt::HANDLE> keys = databaseMap.keys();for(int i= 0; i<keys.count();i++){Qt::HANDLE id = keys[i];//释放内存delete databaseMap.take(id);QSqlDatabase::removeDatabase(QString::number(*(unsigned int*)&id));}
}

三、测试

1、新建一个多线程类

thread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>
#include <QObject>
#include <QString>#include "sqlitehelper.h"class MyThread:public QThread
{
public:MyThread();public:void run() override;
};#endif // MYTHREAD_H

thread.cpp

#include "mythread.h"MyThread::MyThread()
{}void MyThread::run()
{static int cnt = 0;while(1){QThread::sleep(1);auto id = QThread::currentThreadId();int barCode = 0, waybillCode = 0;barCode = *(unsigned int*)&id + cnt;waybillCode = *(unsigned int*)&id + cnt;cnt++;QString sql = QString(R"(INSERT INTO produceTable(barCode,waybillCode,dateTime) VALUES('%1','%2',datetime(CURRENT_TIMESTAMP, 'localtime'));)").arg("barCode"+QString::number(barCode)).arg("waybillCode"+QString::number(waybillCode));SqliteHelper* sqlHelper = SqliteHelper::getInstance();qDebug()<<id<<"  "<<sqlHelper->lockExec(sql);}}

2、开启多线程插入数据

连接一个数据库:

SqliteHelper::changeDatabase("database2.db");

界面中放置一个按钮,按几下开启几个线程。

void MainWindow::on_btnInsertData_clicked()
{MyThread *t = new MyThread();t->start();}
http://www.dtcms.com/wzjs/599875.html

相关文章:

  • 湘潭seo网站优化财务公司经营范围有哪些
  • 湖南建设长沙网站建设价格建筑工程 网络图
  • 织梦如何新建网站微信小程序和网页哪个开发难
  • wordpress 全宽页面网站在线seo
  • 戴尔公司网站建设的特点是什么怎样查网站空间地址
  • 网站开发需要什么专业的人才html5的网站设计与实现是做什么
  • 列出网站开发建设的步骤云南测绘公司最新排名
  • 化工行业网站设计网站做海康直播
  • 做网站都需要考虑哪些做淘宝客网站难吗
  • 凡科 如何建设网站流程做房产网站需要了解什么
  • 做网站多少钱PageAdminwordpress版本控制
  • 网站建设站点地图网址导航可以卸载吗
  • 开发区网站建设工作管理办法企业网站制作套餐
  • 网站设计参考文献有哪些潍坊住房公积金官网登录
  • 目录网站做外链商务网站内容建设包括
  • 网站配资公司网站微信号 网站模板
  • 想做一个静态网页网站不需要有后台数据库广州网站建设公司
  • 厦门高端模板建站一款可做引流的网站源码
  • 怎么注册自己的网站商贸有限公司经营范围
  • 互联网网站备案流程用一个矿泉水瓶子做手工
  • 网站开发php教程礼品网站建设策划
  • 合作建站方案购买帝国cms做网站代理
  • 北京大兴企业网站建设咨询网店装修是什么意思
  • 国家骨干高职院校建设网站邯郸建设网站制作
  • 网站后台怎么管理高德地图是国产软件吗
  • 朝阳网站开发联系电话seo诊断a5
  • 葫芦岛市建设局网站电商网站增加客户
  • 网站如何做导航条下拉菜单启迪网站开发
  • 自己怎么做网站推广做盗版小说网站怎么样
  • 做网站简单需要什么网页模板设计