2013-12-11 50 views
0

我正在寫一個路徑跟蹤器,並希望通過線程進行並行化。我有一個關於QT中多線程對象的設計問題,特別是在QRunnable類中。QThreadPool&QRunnable&靜態函數

在我的(僞代碼)下面,我有一個類「PathTracer」,它啓動了PTRunnable的實例,它擴展了QRunnable。

將QRunnable對象指向創建它們的類的指針是否合適,以便每個QRunnable都可以訪問類(doWork)提供的靜態方法?我的推理是,如果由於某種原因,我希望禁用多線程,那麼PathTracer實例仍然會實現沒有冗餘的必要方法。

還是有更好的設計?私人實例變量m_data會發生什麼?可運行的對象是否會在共享的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]); 
} 

回答

0

更好的方法是讓這些靜態方法插槽和從QRunnable情況下發出的信號/信號發送回來,如果你希望一些回報形成功能QRunnable對象。

這將是線程安全的,您不需要傳遞/存儲任何指針 - 因爲通過傳遞/存儲指針可能會導致嘗試訪問已被刪除的對象。

您可以將指向PathTracer的指針傳遞給PTRunnable的構造函數,如果您想要將所有信號和插槽連接起來,但將指針存儲爲類成員將是一個糟糕的設計思路 - 無需存儲它並存儲隨着代碼的增長,將來會出現錯誤。