QT多线程和移动对象线程创建后
QT Multithreading and Moving Objects Threads after creation
我有一个多线程程序,它从网站下载并获取信息,然后获取信息,创建一个对象,然后用图像将其添加到我的GridLayout中。
我有成千上万的对象,我需要创建,然后添加到我的网格布局,使用8个线程来获得信息,同样的8个线程然后创建对象,并将它们添加到8个不同的网格中。
程序运行大约20秒后,我得到一个
QThread::start:未能创建线程(访问代码无效。)错误。再过几秒钟,我得到了一些运行时C++错误,这些错误挂起并且不显示消息。这意味着什么?让我困惑的是,在这一点上,我的线程已经创建好了,而我实际上并没有创建更多的线程。。在这些线程中,尽管它们每个都在创建Widget对象,然后将它们发送到Main Gridlayout。。
我检查了我运行的线程数量(QThread:idealThreadCount),它只返回8个。
我是多线程从网站下载信息的,然后每条记录都会返回我创建的值到一个Object中,放入我的GridLayout中。
我在想,因为在这一点上,这些对象都属于单个线程,在所有url完成之前永远不会发出(finished()),所以它占用了一些东西并导致了这个错误?
在下载信息并将新对象添加到网格布局后,我是否应该尝试MoveToThread并将所有这些对象发送回主线程?
这些对正在发生的事情有意义吗?如果你想让我发布代码吗?
谢谢。
编辑:
只是在创作后尝试移动线程,但学会了QObject::moveToThread:小工具无法移动到新线程
这是我创建的线程
void checkNewArrivals::createWorkers(QString url, QString category, QString subCategory){
QThread* thread = new QThread;
checkNewArrivalWorker* worker = new checkNewArrivalWorker(url, category, subCategory);
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(result(QString,QString,QString,QString,QString,int, int)), this, SLOT(addItem(QString,QString,QString,QString,QString,int, int)));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
这是我的工人类函数,它会发出结果
void checkNewArrivalWorker::getHtml(QString url){
html = QString::fromStdString(Curl->getWebsiteHtml(url.toStdString()));
html = html.mid(html.indexOf("Goods List"));
html = html.mid(0, html.indexOf("footer"));
for (int i = 0; i < html.count("GoodsBox"); i++){
//blah blah blah blah
emit result(idLink, picLink, price, category, subCategory, row, col);
col++;
if (col == 5){
col = 0;
row++;
}
html = html.replace(itemRow, "");
}
}
然后我添加结果来创建一个项目,并将其添加到网格布局中
void checkNewArrivals::addToGrid(QGridLayout *layout, QString id, QString picUrl, QString usPrice, int row, int col){
checkNewArrivalItem* item = new checkNewArrivalItem;
if (item->setupItem(id, picUrl, usPrice) == true){
layout->addWidget(item, row, col);
};
}
这些项目运行良好,直到我认为项目过载。。不太确定我为什么会出现这个错误。
Qt GUI对象不能存在于主线程之外的任何线程中。GUI对象需要在主线程中创建并添加到布局中。您仍然可以从后台线程收集数据,但需要将其传递回主线程进行显示。为此,我建议使用信号,因为默认情况下信号/插槽连接是线程安全的。
编辑:您的新线程看起来应该可以工作。然而,我认为您会发现最好保持特定数量的线程运行,并将工作委托给它们。首先,创建、启动、停止和销毁线程是一个昂贵的过程。但也许更重要的是,您可能只是创建了太多线程。
需要明确的是,QThread::idealThreadCount()不是您正在运行的线程数,而是您的CPU可以最有效地处理的线程数。我猜你有一个带超线程的四核CPU,它是8。
我认为很可能是您创建了太多线程。这听起来很像我错误地那样做的时候。
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- C++ 线程创建/删除与线程停止/恢复
- Qt - 如何从线程创建 QFuture
- 我可以使用Qt线程ID为每个线程创建唯一的缓存吗?
- 零MQ 后台线程创建
- OpenMP 线程创建
- GLFW & ImGui:从 main 以外的线程创建 ImGui 控件
- 对象:无法为位于不同线程中的父线程创建子级
- C++ 11:线程创建给我一个"Attempt to use a deleted function"错误
- C 的周期性线程创建
- MPI - 当数组初始化值必须为常量时,如何为工作线程创建部分数组
- 当主GUI线程被阻塞时,如何从工作线程创建无模式对话框
- 多个线程创建5个线程来计算质数
- 为线程创建模板
- 线程创建,CRT和DLL是如何完成的?
- 同步线程创建和销毁(静态)对象
- 竞争条件:一个线程创建静态对象,另一个线程在初始化完成之前使用它.如何处理
- 从不同线程创建QMainWindow
- QFuture 无法为位于不同线程中的父线程创建子级
- ( QNativeSocketEngine)QObject:无法为位于不同线程中的父线程创建子级