使用哪个QueuedConnection或QMutex使对象具有线程安全性?

时间:2015-11-01 05:43:30

标签: c++ multithreading qt

我正在构建一个需要加载数千个HTML文件的应用程序,分析它们然后将它们放到像HashMap这样全局的东西中,我决定使用多线程来加快速度。

因此,我应该使用的问题是QueuedConnection for signal / slots或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放入HashMapList的所有方法中,并在analyze()中尝试LoadHtml

1 个答案:

答案 0 :(得分:1)

互斥体将是两者中更快的解决方案,因为在频繁访问的情况下,排队的连接开销将如此之高以至于使用多个线程实际上比使用具有直接连接的单个线程慢得多。

但我会建议一个不同的解决方案,一个更好的解决方案。不是将作业结果直接存储在全局哈希映射中,而是为每个作业创建一个本地哈希映射,并使用它来存储结果,并且只有在作业完成后,才能将本地的结果合并到全局哈希中地图。这将最小化排队连接或互斥锁定/解锁,从每个单词一次到每个作业一次。这将为您提供最佳性能。这样,使用排队连接或互斥锁之间的差异可以忽略不计,因此您可以简单地使用更简单,更清洁的解决方案。

但是,看一下您的代码示例,我认为性能不是您当前关注的问题。这是你的实际代码,还是一个非常非常糟糕的例子?这没有意义。