1

boost::threadpool我正在尝试使用(不是boost, link的官方部分)来并行化我的程序的某个方面。但是,我发现我的程序停顿了,经过检查,htop显示有两个非活动线程(我怀疑在我的线程池中)和一个线程以 100% 运行(我怀疑我的主执行线程)。

以下是相关代码:

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时,程序不会进入它的无限循环。我在这里做错了什么?

4

2 回答 2

1

给出的参数boost::bind 将被复制

bind 接受的参数由返回的函数对象在内部复制和保存。例如,在以下代码中:

诠释 i = 5;

绑定(f,我,_1);i 的值的副本存储到函数对象中。boost::ref 和 boost::cref 可用于使函数对象存储对对象的引用,而不是副本。

在你的情况下:

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

cam将发送, image,xyto的副本Rendered::render。那是你的意图吗?

于 2011-02-04T15:50:52.683 回答
1

您是否考虑过使用 boost::thread_group 作为即兴线程池?此处使用的 wait() 的实现是什么,这个名称暗示了一个障碍,这可能是您的线程无限期地变为非活动状态的原因。

编辑:

你可以在不进入无限循环的情况下调用渲染吗?可能是您跟踪或产生未显示的光线的方式。此外,您可能希望wait_for_all_tasks根据您发布到其实现的链接的简要介绍来调用您的线程池。

于 2011-02-03T23:46:05.140 回答