首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtConcurrent线程很慢!!我做错了什么?

QtConcurrent线程很慢!!我做错了什么?
EN

Stack Overflow用户
提问于 2012-12-11 23:00:34
回答 2查看 2.5K关注 0票数 1

为什么我的qtconcurrent::run()调用和通过对象调用成员函数一样慢?

( QtConcurrent::run(&db, &DBConnect::loadPhoneNumbers)就像调用db.loadPhoneNumbers()一样慢)

请阅读下面进一步的解释。

我一直试图通过QtConcurrent::run创建一个线程,以帮助加快将数据发送到SQL数据库表的速度。我使用一个成员变量,它是一个QMap,并遍历它将每个key+value发送到数据库。

QtConcurrent::run()调用的成员函数:

代码语言:javascript
复制
void DBConnect::loadPhoneNumbers()
{

//m_phoneNumbers is a private QMap member variable in DBConnect
qDebug() << "\t[!] Items to send: " << m_phoneNumbers.size();

QSqlQuery query;
qDebug() << "\t[!] Using loadphonenumbers thread: " << QThread::currentThread();
qDebug() << "\t[!] Ideal Num of Threads: " << QThread::idealThreadCount();

bool isLoaded = false;

QMap<QString,QString>::const_iterator tmp = m_phoneNumbers.constBegin();

while(tmp != m_phoneNumbers.constEnd())
{
    isLoaded = query.exec(QString("INSERT INTO "+m_mtable+" VALUES('%1','%2')").arg(tmp.key()).arg(tmp.value()));

    if(isLoaded == false)
    {
        qDebug() << "\r\r[X] ERROR: Could\'t load number " << tmp.key() << " into table " << m_mtable;
        qDebug() << query.lastError().text();
    }

    tmp++;
}

}

调用线程的main.cpp节

代码语言:javascript
复制
DBConnect db("QODBC", myINI.getSQLServer(),C_DBASE,myINI.getMTable(), myINI.getBTable());
db.startConnect();

//...more code here

     qDebug() << "\n[*] Using main thread: " << QThread::currentThread() << endl;

         //....two qtconcurrent::run() threads started and finished here (not shown)

         qDebug() << "\n[*] Sending numbers to Database...";
         QFuture<void> dbFuture = QtConcurrent::run(&db, &DBConnect::loadPhoneNumbers);
         dbFuture.waitForFinished();

我对形势的理解

根据我的理解,这个线程将在一个新的线程池下运行,这个线程池与主线程分离。我看到的不是这种情况(请注意,还有另外两个QtConcurrent::run()调用在此之前对数据库进行调用,所有这些调用在继续进行数据库调用之前都要完成)

现在,我考虑使用QtConcurrent::map() /map(),但无法使它在QMap中正常工作。(找不到任何例子来帮助他们,但除了这件事.如果有人问我为什么不使用FYI,那只是一个FYI)

在我的测试中,我使用QThread::currentThread()查找当前正在调用的线程。这就是我的程序中不同线程正在发生的情况。(所有in并发::run()调用都是在main.cpp FYI中进行的.不确定这是否有区别)

代码语言:javascript
复制
Check what is main thread: on QThread(0x5d2cd0)
Run thread 1: on QThread(0x5dd238, name = "Thread (pooled)")
Run thread 2: on QThread(0x5d2cd0)
Run thread 3 (loadPhoneNumbers function): on QThread(0x5d2cd0)

如上文所示,除了第一个qtconcurrent::run()调用之外,其他所有东西都在主线程(o.O)上。

问题:

据我理解,我的所有线程(所有qtconcurrent::run)都应该在它们自己的线程上(只有第一个线程是)。这是真的还是我遗漏了什么?

其次,我的loadPhoneNumebrs()成员函数线程安全吗?(因为我没有改变我所能看到的任何东西)

最大的问题:,为什么我的loadPhoneNumbers() qtconcurrent::run调用速度和调用成员函数一样慢?(例如:db.loadPhoneNumbers()和qtconcurrent::run()版本一样慢)

任何帮助都非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-12 00:30:34

线程不会神奇地加快速度,它们只是为了在后台发生时继续做其他的事情。当您调用waitForFinished()时,您的主线程将在load线程完成之前不会继续,这在本质上否定了这个优势。根据实现的不同,这可能是您的currentThread()显示与main相同的原因,因为等待已经发生。

就速度而言,可能更重要的是构建一个在列表中插入所有值的查询,而不是对每个值进行单独的查询。

票数 2
EN

Stack Overflow用户

发布于 2012-12-12 19:47:35

根据QtSql文档:

只能从创建连接的线程中使用连接。不支持在线程之间移动连接或从其他线程创建查询。

它无论如何都能工作,因为ODBC本身支持对单个ODBC句柄的多线程访问。但是,由于您只使用一个连接,所以所有查询都可能被ODBC序列化,就好像只有一个线程一样(例如,请参见Oracle的ODBC驱动程序是做什么的)。

waitForFinished()调用一个私有函数stealRunnable(),顾名思义,它从QFuture队列中接受一个尚未启动的任务,并在当前线程中运行它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13829949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档