QThreadPool& QRunnable&静态函数

时间:2013-12-11 00:32:38

标签: c++ multithreading qt static-methods

我正在编写一个路径跟踪器,并希望通过线程使其并行化。我有一个关于QT中多线程对象的设计问题,特别是在QRunnable类上。

在下面的我的(伪代码)中,我有一个类“PathTracer”,它启动了PTRunnable的实例,它扩展了QRunnable。

向QRunnable对象传递指向创建它们的类的指针是否合适,以便每个QRunnable可以访问类提供的静态方法(doWork)?我的理由是,如果由于某种原因我希望禁用多线程,PathTracer实例仍然会实现没有冗余的必要方法。

还是有更好的设计?私有实例变量m_data会发生什么? qrunnable对象是在共享m_data上运行,还是会生成指针数据的副本?

#include <QThreadPool>
#include <vector>

class PathTracer
{
public:
    static void doWork(PathTracer * pt, Pixel pix);
protected:
    void renderImage();
    void modifyData();
private:
    int m_data;
};

PathTracer::renderImage()
{
    for (int x=0; x<width; x++)
    {
        for (int y=0; y<height; y++)
        {
            pixelblock.push_back(Pixel(x,y));
        }
    }
    // pass instance of self to each worker
    PTRunnable ptworker(this, pixelblock);
    QThreadPool::globalInstance()->start(ptworker);
};

void modifyData()
{
    m_data++;
}

static void PathTracer::doWork(PathTracer * pt, Point p)
{
    pt->modifyData();
}

//////////////////////////////

class PTRunnable : public QRunnable
{
    Q_OBJECT
public:
    explicit PTRunnable(QObject *parent = 0);
    PTRunnable(PathTracer * pt, PixelList pixels);
    void run(); // runnable implementation goes here
signals:

public slots:

private:
    PathTracer * m_pt; // owns pointer to pathtracer that spawned this
protected:

};


PTRunnable::PTRunnable(PathTracer * pt, PixelBlock block)
{
    m_pt = pt;
}
void PTRunnable::run()
{
    pt->doWork(this, block[0]);
}

1 个答案:

答案 0 :(得分:1)

更好的方法是使那些静态方法插槽并从QRunnable实例发出信号/将信号发送回QRunnable对象,如果你期望函数返回一些。

这将是线程安全的,您不需要传递/存储任何指针 - 因为通过传递/存储指针,您可能会遇到尝试访问已删除的对象的潜在风险。

您可以将指向PathTracer的指针传递给PTRunnable的构造函数,以便在需要时将所有信号和插槽连接到那里,但将指针存储为类成员将是一个糟糕的设计理念 - 无需存储它并存储它随着代码的增长,将来会出错。