Я пишу трассировщик путей и хотел бы сделать его распараллеленным по потокам. У меня вопрос проектирования многопоточных объектов в QT, особенно в классе QRunnable.QThreadPool & QRunnable & static functions
В моем (псевдокоде) ниже у меня есть класс PathTracer, который запускает экземпляры PTRunnable, который расширяет QRunnable.
Уместно ли передавать объекты QRunnable указателю на класс, который создает их, чтобы каждый QRunnable мог получить доступ к статическим методам, предоставляемым классом (doWork)? Мое рассуждение состоит в том, что если по какой-то причине я хочу отключить многопоточность, экземпляр PathTracer будет по-прежнему иметь необходимые методы без избыточности.
Или есть лучший дизайн? Что произойдет с переменной private экземпляра 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]);
}