zoukankan      html  css  js  c++  java
  • QT database连接问题

    在一个QT-Mysql的项目中,偶尔出现连接数据库很慢和连接失败的现象,查看后台能看到这样的警告

    Error in my_thread_global_end(): 1 threads didn't exit

    后来在qt论坛上看到类似的问题,提问者给出了以下代码,用100个线程同时连接数据再断开,果然能重现问题。

    class Client: public QRunnable
    {
    public:
        virtual void run();
    };
    void Client::run()
    {
        QString sID = QString::number((unsigned long long)QThread::currentThreadId());
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", sID); // unique connection name
    
        db.setHostName("localhost");
        db.setDatabaseName("test");
        db.setUserName("me");
        db.setPassword("mypass");
    
        db.open();
        // do something query...
        db.close(); // 对象并未释放,无法remove
        QSqlDatabase::removeDatabase(sID);
    }
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QThreadPool pool;
        pool.setMaxThreadCount(100);
    
        for (int i = 0; i < 100; ++i)
        {
            Client *client = new Client;
            bool started = pool.tryStart(client);
            Q_ASSERT(started);
        }
        pool.waitForDone();
        return 0;
    }

    不过先出了另一个问题:removeDatabase: connection '**' is still in use, all queries will cease to work

    查了一下,原因是QSqlDatabase对象close()时连接并未完全释放,也就无法remove. 改成指针的形式可以解决  

        QSqlDatabase *pdb = new QSqlDatabase();
        *pdb = QSqlDatabase::addDatabase("QMYSQL", sID); // unique connection name
        pdb->set...;
        pdb->open();
        pdb->close();
        delete pdb; // 释放对象
        pdb = NULL;
        QSqlDatabase::removeDatabase(sID);

    解决这个之后,连接数据库很慢和失败、警告都出现了。经过反复尝试,发现QSqlDatabase::addDatabase/open不是线程安全的, 不能被打断,加锁保护后完全正常了。

    QMutex gMutexdb; // global mutex for db-open
        gMutexdb.Lock();
        *pdb = QSqlDatabase::addDatabase("QMYSQL", sID); // unique connection name
        pdb->set...;
        pdb->open();
        gMutexdb.Unlock();

    不过这种多数据库连接,应该做一个连接池来管理。

  • 相关阅读:
    JavaScript设计模式 Item 6 --单例模式Singleton
    把上个JDBC Request查询出来的结果当成下个JDBC Request查询的参数
    Jmeter连接数据库
    Jmeter 消息体使用csv参数化时编码问题
    在fiddler中设置断点修改数据(二)
    在fiddler中设置断点修改数据(一)
    抓包工具fiddler的安装与配置
    解决配置fiddler时信任证书报:Unable to configure Windows to Trust the Fiddler Root certificate.The LOG tab may contain more infor
    截图贴图神器Snipaste
    Jmeter 字符串拼接参数
  • 原文地址:https://www.cnblogs.com/chaos77/p/6677024.html
Copyright © 2011-2022 走看看