2011-02-03 43 views
1

我想使用boost::threadpool(不是boostlink的官方部分)並行我的程序的某個方面。然而,我發現我的程序停滯,並經過檢查,htop顯示有兩個不活動的線程(我懷疑在我的線程池中)和一個線程以100%運行(我懷疑我的主執行線程)。使用boost :: threadpool與boost :: bind掛起我的程序在一個無限循環

下面是相關代碼:

namespace rt { 

class Renderer 
{ 
    public: 
    Renderer(int threads) : tp(threads) {} 

    void render(const Scene&, const Camera&, Image&) const; 

    private: 
    mutable boost::threadpool::pool tp; 
    //int tp; 

    static void render(const Scene&, const Camera&, Image&, int, int); 
    static Color trace_ray(const Ray&, const Scene&, int depth = 0); 
}; 

} // namespace rt
void 
Renderer::render(const Scene& scene, const Camera& cam, Image& image) const 
{ 
    for (int y = 0; y < image.get_height(); ++y) 
     for (int x = 0; x < image.get_width(); ++x) 
      tp.schedule(boost::bind(&Renderer::render, scene, cam, image, x, y)); 

    tp.wait(); 
} 

void 
Renderer::render(const Scene& scene, const Camera& cam, Image& image, int x, int y) 
{ 
    Color c = trace_ray(cam.spawn_ray(x + .25f, y + .25f), scene) 
      + trace_ray(cam.spawn_ray(x + .75f, y + .25f), scene) 
      + trace_ray(cam.spawn_ray(x + .25f, y + .75f), scene) 
      + trace_ray(cam.spawn_ray(x + .75f, y + .75f), scene); 

    image.set_pixel(x, y, c/4.0f); 
}

我懷疑問題在於我boost::bind結構的原因是,當我創建一個void foobar() {}功能,並傳遞到boost::threadpool::pool::schedule,該方案沒有得到進入它的無限循環。我在這裏做錯了什麼?

+0

是什麼讓你認爲問題出在boost綁定或線程池,而不是你的代碼?這聽起來像你有同步問題,導致實時鎖定。 – 2011-02-04 03:09:24

+0

這可能也是可能的,我只是重寫我的代碼使用`asio :: io_service`而不是`boost :: threadpool`,並且同樣的錯誤仍然存​​在。但是,我不知道它可能鎖定的位置。正如你可以在下面的`render`函數中看到的那樣,所有的函數都會跟蹤一些獨立的光線並在圖像中設置一個值(它基本上只是一個大數組)。由於每個線程只訪問數組中的一個不同的元素,並且只寫入,所以我不明白它是如何導致實時鎖定的......這就是爲什麼我認爲我可能使用`boost :: bind`錯誤。 – robrene 2011-02-04 10:43:55

+0

另外,另一件事:當我在線程池中只有一個線程時,它仍然掛起。所以這看起來不像一個併發問題。 – robrene 2011-02-04 11:35:01

回答

1

給出的參數爲boost::bindwill be copied

結合需要被 複製並在內部由 保持的參數返回的函數的對象。例如, 代碼如下:

int i = 5;

bind(f,i,_1); i的值的副本存儲在函數對象中。 boost :: ref和boost :: cref可用於 以使函數對象存儲對象的引用 ,而不是 副本。

你的情況:

tp.schedule(boost::bind(&Renderer::render, scene, cam, image, x, y)); 

將派出camimagexyRendered::render副本。那是你的意圖嗎?

1

你有沒有考慮過使用boost :: thread_group作爲即興線程池呢?這裏使用的wait()的實現是什麼,這意味着一個障礙,這可能是爲什麼你的線程無限期變得無效。

編輯:

你可以調用渲染而不會進入無限循環嗎?也許它是在你追蹤或產生未顯示的光線的方式。此外,看起來您可能希望在您的線程池中調用wait_for_all_tasks,方法是簡要了解您發佈到其實現的鏈接。

相關問題