tune2fs
tune2fs

Reputation: 7705

boost::thread runtime error when generating threads

I have a project where we want to provide to use threads to speed up everything. We want to be able to call this function in individual threads:

Request& Filter::processRequest(Request& req)

Therefore I packed the function in lambda expression to have access to the return value.

I now get the following runtime error:

  glibc detected ... double free or corruption (!prev): ...

When I uncomment the line where I add the thread to the group everything works fine.

boost::thread_group thread;
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin();
    i != sources_.end(); ++i) {
         Request ret
         thread.add_thread(new boost::thread(boost::lambda::var(ret) = 
            (*i)->processRequest(req)));
         req+=ret;
         ...
}
thread.join_all();

What can be the reason for this runtime error. Or is there another way to put this function in individual threads?

Upvotes: 0

Views: 414

Answers (1)

If this sort of technique were to work at all, you would need multiple ret values that you could stably reference (one for each thread of execution). And you'd have to wait until after your thread join completed until you used those values.

A simple modification you can try would just be to make a vector outside of the loop of vector<Request> retValues...and then add an element to the vector each time you add_thread and pass a reference to that element. Then if you wait until after the join to use the values, perhaps it would work?

boost::thread_group thread;
vector<Request> retValues;
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin();
    i != sources_.end(); ++i) {
         retValues.push_back(0);
         thread.add_thread(new boost::thread(
            boost::lambda::var(retValues.back()) = 
            (*i)->processRequest(req)));
         ...
}
thread.join_all();
// retValues safe to use here...

(Note: Using boost::lambda is probably not necessary; you can use boost::bind to connect to a worker class that stores the result:

Getting return value from a boost::threaded member function?

...but really, no matter what you'll need a separate variable per thread to store the result...whose lifetime lasts long enough for the thread to be able to write to it.)

Upvotes: 1

Related Questions