Flo
Flo

Reputation: 1671

Create Threads in a loop

I just tested something like this:

boost::thread workerThread1(boost::bind(&Class::Function, this, ...);
boost::thread workerThread2(boost::bind(&Class::Function, this, ...);

and it works fine. What i now want, is to create as many Threads as i have objects in a list. I have experimentet with boost::foreach and this works fine. But i have problems with the names of the threads.

So simplified the code looks like this:

for
{
    boost:thread name(...);
}

but of course name cant be right here in the loop because it overwrites itself and isnt accessible after the loop. How do i create the threads so that i can join them all after all have been created?

Upvotes: 4

Views: 14960

Answers (5)

ali_bahoo
ali_bahoo

Reputation: 4873

Why don't you use boost::thread_group? You can create/add/remove threads and join them all (boost::thread_group::join_all()).

boost::thread_group tgroup;
for(...)
{
  tgroup.create_thread(boost::bind(&Class::Function, this, ...)) ;
}
tgroup.join_all();

But be careful about the number threads you are creating, too many threads may lead to OutOfMemory.

Upvotes: 12

Firedragon
Firedragon

Reputation: 3733

Can you not just create a list (or similar) of threads and then just create them and add to the list.

Something like the following (which is likely more pseudo code that anything :-) )

list<boost::thread*> threads;

for
{
    boost::thread* name = new boost::thread(...);
    threads.push_back(name);
}

As mentioned in another answer you can use smart pointers which would be better and you mentioned you have a defined number of threads so an array/vector would be a better choice but as I said the code above isn't perfect anyway

Upvotes: 4

Mike Seymour
Mike Seymour

Reputation: 254751

You can keep them in an array:

size_t const thread_count = 5;
boost::thread threads[thread_count];
for (size_t i = 0; i < thread_count; ++i) {
    threads[i] = boost::bind(&Class::Function, this, ...));
}

In C++11, you can keep std::thread in friendlier containers such as std::vector:

std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
    threads.push_back(std::thread(boost::bind(&Class::Function, this, ...))));
}

This won't work with boost::thread in C++03, since boost::thread isn't copyable; the assignment from a temporary in my example works because of some Boost magic that sort-of emulates move semantics. I also couldn't get it to work with boost::thread in C++11, but that might be because I don't have the latest version of Boost. So in C++03, your stuck with either an array, or a container of (preferably smart) pointers.

Upvotes: 3

Patrick87
Patrick87

Reputation: 28332

Disclaimer: I don't use boost, but if it works like the rest of C++, I believe this might be along the right lines. Will delete if this is garbage.

boost::thread** threads;
threads = new boost::thread*[THREAD_COUNT];

for(int i = 0; i < THREAD_COUNT; i++)
{
   threads[i] = new boost::thread(...);
}

...

for(int i = 0; i < THREAD_COUNT; i++)
   delete threads[i];

delete[] threads;

...

The idea is just to dynamically allocate an array of pointers to your object type, based on how many you want. Then, for each one, dynamically create one and invoke the appropriate constructor in a loop. Eventually, you will/may need to clean these up, so you can use delete[] calls. I don't see why malloc() / free() and/or vector types wouldn't work, either.

Upvotes: 0

Mark B
Mark B

Reputation: 96311

Why not put the threads into their own container, such as a vector (by smart pointer assuming they're non-copyable)?

Upvotes: 2

Related Questions