我正在构建一个应用程序,需要加载数千个 HTML文件,分析它们,然后将它们放入像HashMap这样的全局,我决定使用多线程来加快速度.
因此,我应该使用QueuedConnection信号/槽或QMutex以使HashMap线程安全.
我使用QueueConnection使一切变得更简单,我创建了许多子线程来加载并将指针发送回主线程以分析它们并将它们放入HashMap中,它工作正常.
但是,当我读到一些注释时,QueueConnection实际上非常耗时,然后我开始重新构建我的代码并使用QMutex使我的HashMap线程安全,然后我可以完成所有工作(加载,分析,将它们放入HashMap)在子线程中.
但结果不是很乐观,后者比前者消耗更多的时间.
QueueConnection真的是一种更好的工作方式吗?
示例代码如下:
使用QueuedConnection:
class Html
{
void create();
{
/* Load from local file */
}
void analyze()
{
/* Pick out every word and put them into the inverted list */
QString word = this->getNextWord();
/* What's stored in the hashmap is a list */
List list = HashMap::globalInstance()->getList(word);
/* Do some work like checking */
list->append(this);
}
}
class LoadHtml : public QThread
{
signals:
void processHtml(Html* ptr);
public:
void run()
{
Html* ptr = new Html();
ptr->create();
emit processHtml(ptr);
}
}
class MainThread: public QThread
{
private:
LoadHtml loadHtml;
slots:
void processHtml(Html* ptr)
{
ptr->analyze();
}
void run()
{
connect(&loadHtml,LoadHtml::processHtml,this,MainThrad::processHtml,Qt::QueuedConnection);
loadHtml.start();
}
}
而QMutex版本就像删除信号/插槽一样,将QMutex放在HashMap和List的所有方法中,并尝试在LoadHtml中进行analyze().
最佳答案 互斥体将是两者中更快的解决方案,因为在频繁访问的情况下,排队的连接开销将如此之高以至于使用多个线程实际上比使用具有直接连接的单个线程慢得多.
但我会建议一个不同的解决方案,一个更好的解决方案.不是将作业结果直接存储在全局哈希映射中,而是为每个作业创建一个本地哈希映射,并使用它来存储结果,并且只有在作业完成后,才能将本地的结果合并到全局哈希中地图.这将最小化排队连接或互斥锁定/解锁,从每个单词一次到每个作业一次.这将为您提供最佳性能.这样,使用排队连接或互斥锁之间的差异可以忽略不计,因此您可以简单地使用更简单,更清晰的解决方案.
但是,看看你的代码示例,我认为性能不是你当前关注的问题.这是你的实际代码,还是一个非常非常糟糕的例子?这没有意义.