2

I'd like to use Boost to create n threads, each invoking a method on an object, and then join_all to wait for them all to complete. I'd expect this would be simple using thread_group and join_all, but I'm confused about the following:

  1. While thread allows passing an object and method, thread_group::create_thread doesn't. This can be worked around (as in How to pass function parameters to boost::thread_groups::create_thread() ), but I'm not sure if there's a reason for that difference; if there is, I'd like to know what the rationale is before I steamroll through it.

  2. I'm not sure about scope and lifetime of both the thread and the object I'm passing it. My understanding is that with simple threads, both the thread and the passed object can go out of scope with no problem: the actual system thread stays running, and the passed object is copied. But, here again, thread_group seems to complicate this, especially if I need to use new (as per that workaround referenced above).

  3. Finally, if I do use new, who does the delete? I've tried to figure out how to use a smart pointer, but then the delete seems to happen in the for loop, before the join_all call.

My code so far is:

for (int i = 0; i < numThreads; i++) {
    W w = W(...);
    //threadGroup.create_thread(&W::work, &w); // Won't work, create_thread won't take params
    boost::thread(&W::task, w);
}
Community
  • 1
  • 1
SRobertJames
  • 8,210
  • 14
  • 60
  • 107

1 Answers1

0

Use a thread group with bind.

Below, w will be bound by value into the bind expression (so it's copied). See e.g. boost::bind() copies by reference or by value?

If your worker is not copyable instead of the new approach consider

  • using move: bind(&W::work, std::move(w)) or, just bind(&W::work, W("some", 42, "args"))
  • using a shared_ptr (boost bind will know how to invoke member functions on it

Live On Coliru

#include <boost/thread.hpp>

static const int numThreads = 10;

struct W {
    W(...) {}

    void work() {
    }
};

int main()
{
    boost::thread_group tg;
    for (int i = 0; i < numThreads; i++) {
        W w = W("some", 42, "args");
        tg.create_thread(boost::bind(&W::work, &w));
    }

    tg.join_all();
}
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633