ejang
ejang

Reputation: 4062

QThreadPool & QRunnable & static functions

I am writing a path tracer and would like to make it parallelized via threads. I have a design question regarding multithreaded objects in QT, specifically on the QRunnable class.

In my (pseudocode) below, I have a class "PathTracer" that launches instances of PTRunnable, which extends QRunnable.

Is it appropriate to pass QRunnable objects a pointer to the class that creates them so that each QRunnable can access static methods provided by the class (doWork)? My reasoning is that if for some reason I wish to disable multithreading, the PathTracer instance will still have the necessary methods implemented without redundancy.

Or is there a better design? What will happen to the private instance variable m_data? will the qrunnable objects be operating on shared m_data, or will a copy of the pointer data be made?

#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]);
}

Upvotes: 0

Views: 957

Answers (1)

Ilya Kobelevskiy
Ilya Kobelevskiy

Reputation: 5345

Better approach would be to make those static methods slots and emit signals from QRunnable instances/send signals back to QRunnable objects if you expect some return form the functions.

This will be thread safe, and you will not need to pass/store any pointers - since by passing/storing pointers you run into potential risk of trying to access obejcts that have been deleted.

You can pass pointer to PathTracer to constructor of PTRunnable to connect all signals and slots there if you want to, but storing a pointer as class member would be a bad design idea - there is no need to store it, and storing it will be error prone in future as code grows.

Upvotes: 1

Related Questions