c++ - 如何用 QtConcurrent 替换 Qthread

标签 c++ multithreading qt qthread qtconcurrent

我有一个连接到 SQL 并获取所需数据的 SQL 获取类。

我想在另一个线程中执行此操作,因此我使用 QThread 执行了此操作。 它正常工作。

但是现在想换成QTConcurrent。 我在使用 QTconcureent 时面临的问题是,我需要一个连接命令,该命令在线程用于执行 SQL 查询之前初始化数据库。

这是我创建的代码是公共(public)插槽,qint64TotalSize 是 SqlFetcher 类的公共(public)方法。

Controller::Controller(QObject *parent) : QObject(parent)
{
    SqlFetcher* m_Fetcher = new SqlFetcher();

    qInfo() <<"Start"<< QThread::currentThread();

     QFutureWatcher<void> watcher;
     QFuture <void> future1 = QtConcurrent::run(m_Fetcher,&SqlFetcher::qint64TotalSize);

     watcher.setFuture(future1);


    //QThread* t1 = new QThread();
    //m_Fetcher->moveToThread(t1);

    //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::createDb);
    //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::qint64TotalSize);
    //t1->start();


    qInfo() <<"Finish"<< QThread::currentThread();

}

void SqlFetcher::qint64TotalSize()
{
    qint64 l_result= 0;
    QSqlQuery l_query;

    if (m_sqldb.isValid())
    {
        m_sqldb.open();

        if ((m_sqldb.isOpen()))
        {
            l_query.prepare("SELECT COUNT(*) FROM table1");
            l_query.exec();

            if (l_query.next()) {
                l_result= l_query.value(0).toInt();
            }
            m_sqldb.close();
        }
    }

    qInfo() << l_result << QThread::currentThread();
}

void SqlFetcher::createDb()
{
    m_sqldb = QSqlDatabase::addDatabase("QSQLITE");
    m_sqldb.setDatabaseName("xyz.db");
     qInfo() << "createDB" << QThread::currentThread();
}


我当前的输出是

Start QThread(0x7feab4c0f060)
Finish QThread(0x7feab4c0f060)
0 QThread(0x7feab4d42070, name = "Thread (pooled)")

Expected Output or Output with Qthread is

Start QThread(0x7fe82140f060)
Finish QThread(0x7fe82140f060)
createDB QThread(0x7fe82155c840)
151 QThread(0x7fe82155c840)

最佳答案

尝试在 run 中执行整个任务,例如

QtConcurrent::run([](){

    SqlFetcher m_Fetcher;
    m_Fetcher.createDb();
    m_Fetcher.qint64TotalSize();
});

由于我们正在处理并发性,因此使用命名连接会更安全(否则每次都会使用相同的默认连接,可能会被多个线程使用)。您可以通过向 SqlFetcher::createDb 添加一个参数来管理它:

void SqlFetcher::createDb(const QString & connectionName)
{
    m_sqldb = QSqlDatabase::addDatabase("QSQLITE", connectionName);
    // etc.

还有 lambda 和 run 函数:

QtConcurrent::run([](const QString & cn){

    SqlFetcher m_Fetcher;
    m_Fetcher.createDb(cn);
    m_Fetcher.qint64TotalSize();
}, QString("TheConnectionName"));

在另一个函数中,将数据库分配给查询,在构造中:

void SqlFetcher::qint64TotalSize()
{
    qint64 l_result= 0;
    QSqlQuery l_query(m_sqldb);
    //etc.

关于c++ - 如何用 QtConcurrent 替换 Qthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58542611/

相关文章:

c++ - 为什么STL算法明确需要两个迭代器?

java - 通知调用方法线程中发生的异常

c# - MongoDb Upsert死锁

c++ - 如何将 Qt 应用程序部署到其他系统?

c++ - 是否不可能将 STL 映射与结构一起用作键?

c++ - 从指针 vector 的 vector 中释放内存

python - Python套接字对象是线程安全的吗?

python - 为什么在接受 PyQt4 QDialog 时不会调用 closeEvent 和 destroyed slot?

c++ - 创建用于构建 32 位应用程序的工具包

C++11 使用代理将成员函数传递给线程