将 boost::threadpool 与 boost::bind 一起使用会使我的程序陷入无限循环

发布于 2024-10-16 04:55:38 字数 1578 浏览 9 评论 0原文

我正在尝试使用 boost::threadpool (不是 boost 的官方部分,链接)。但是,我发现我的程序停止运行,经过检查,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,程序不会进入无限循环。我在这里做错了什么?

I'm trying to parallelise a certain aspect of my program using boost::threadpool (not an official part of boost, link). However, I am finding my program stalls and upon inspection, htop shows me that there are two inactive threads (I suspect in my threadpool) and one thread running at 100% (I suspect my main execution thread).

Here is the relevant code:

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

The reason I suspect the problem lies with my boost::bind construct is that when I create a void foobar() {} function and pass that to boost::threadpool::pool::schedule, the program does not get into it's infinite loop. What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

舞袖。长 2024-10-23 04:55:38

boost::bind 的参数 将被复制

bind 采用的参数是
复制并由内部保存
返回的函数对象。例如,
在以下代码中:

int i = 5;

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

在您的情况下:

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

camimagexy 的副本发送到 Rendered: :渲染。这就是你的意图吗?

The arguments given to boost::bind will be copied.

The arguments that bind takes are
copied and held internally by the
returned function object. For example,
in the following code:

int i = 5;

bind(f, i, _1); a copy of the value of
i is stored into the function object.
boost::ref and boost::cref can be used
to make the function object store a
reference to an object, rather than a
copy.

In your case:

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

will send copies of cam, image, x, and y to Rendered::render. Is that what you intend?

南渊 2024-10-23 04:55:38

您是否考虑过使用 boost::thread_group 作为临时线程池?这里使用的 wait() 的实现是什么,这个名字意味着一个障碍,这可能就是你的线程无限期地变得不活动的原因。

编辑:

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

Have you considered using boost::thread_group as impromptu thread pool instead? What is the implementation of wait() being used here the name would imply a barrier which could be why your threads are becoming inactive indefinitely.

Edit:

Can you call render without going into an infinite loop? Perhaps it is in the way you are tracing or spawning rays which is not shown. Also it looks like you may want to call wait_for_all_tasks on your thread pool based on a brief glimpse at the link you posted to it's implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文