
文档上对多线程下数据库应用的注意事项写的很简明,一个线程创建的 QSqlDatabase 对象和 查出来的 QSqlQuery 对象只能给本线程用(注意,是对象,不是数据库连接本身,连接本身用名字可以多线程使用),其他情况是“不支持的”。在一个需要有几个线程并发访问不同数据库的应用中,我首先试图在各个线程的起始分别以不同的名称调用 addDatabase / database 、open,但是程序偶然会崩溃,跟踪后发现,虽然Qt 声称很多方法是“线程安全”的,但是几个方法串起来,就出问题了。Qt 会动态的加载数据库的plugin, 加载 plug in 的部分,涉及到对本地库文件的管理,这一部分,出现了竞争。于是,很自然的想到在初始连接部分设置 Mutex 保护,从 addDatabase / database到 open 的部分,要保证其原子性,问题再也没有出现。
2、数据库连接意外断裂后,恢复连接的问题
在MFC 中,一旦中途TCP连接断裂,直接重新 Open 就可以了。在Qt 里,这一招不好使了。即便 调用了 close ,再次open 也是不行的。处理方法:
在检测到问题出现后,关闭连接,并 removeDatabase; 而后,不要立刻 addDatabase, 反而是要回到该连接所在的事件循环。没有详细跟源码,很可能在 removeDatabase 后的事件循环中,Qt 内部做了一些释放 *** 作。 怎么办呢, 可以设置一个恢复定时器,比如 1分钟,重新 addDatabase,就可以啦。如果心急的话,直接显式调用processEvent() 方法强制循环。
在多线程下,注意1中的问题,需要 Mutex保护。
3、数据库插件的依赖性问题
在 Windows 下,有时我们的机器上按了好几个 Qt 版本,PATH里索性神马也不设置,依赖开发环境的继承环境适应不同的版本。这有两个问题。一是发布程序的时候,数据库驱动依赖的dll 也要与可执行文件在同一路径下发布。比如 mysql 的 dll, PostgreSQL 的依赖等。二是在集成开发环境中,这些依赖也要位于执行档文件夹下。否则,会造成虽然可以枚举到可用驱动,但是死活连接不上。调试一下就知道,原来是在路径中找不到依赖项,导致dll加载失败哦!
QT线程是独立的类:在QT中添加C++类,头文件引用#include <QThread>类公开,这样写:
class XXXX:public QThread,类里面申明Q_OBJECT,直接写在里面。signals: XXX()这是你的订阅事件名。private:void run()这是run函数;public: int cona=3这是变量,一定要public。
cpp文件里引用头文件,run函数里面写方法:
void XXXX::run()
{
do
{
msleep(cona)
emit connec()
}while(true)
}
上面就是线程类了。现在我们在窗体中应用,先在头文件申明
头文件private: XXXX *thread1XXXX *thread2
构造函数中初始化他们
thread1=new XXXX()
thread1->cona=3
QObject::connect(thread1,SIGNAL(connec()),this,SLOT(XXX信号1()))
thread2=new XXXX()
thread2->cona=4
QObject::connect(thread2,SIGNAL(connec()),this,SLOT(XXX信号2()))
XXX信号1()是读A数据,XXX信号2()读B数据。
按钮1的信号槽里写方法同时进行每3秒读A、没4秒读B
thread1->start()
thread2->start()
要结束谁就用 xxxx->terminate()
看明白没?QT可不同与C++,你不熟悉编程环境,是很难理解的。
Qt不是语言,是一个c++类库,多用来编写界面,但是qt类库实际上非常全面,多线程、数据库支持、IO和网络都支持。qt有自己的IDE qtcreator,也可以挂载在vs开发,支持跨平台(windows、linux),安卓也支持但是不推荐用qt写安卓。Qt的文档完整性和可读性非常高,是真正可以照着文档编程的(每个函数都有实例,每个参数都有解释),目前语言支持c++(qt widget项目)、python(pyQt)、Qml(Qt quick项目),qml是qt自己的脚本,类似js欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)