Invoke several functions with the same thread
Hi Guys I am trying to convert my application to a multithreaded app. Please see code below: boost::thread_group threads; FileThread *fThreads[filearr.size()]; for(int i=0; i < filearr.size(); i++) { fThreads[i] = new FileThread(filearr[i]); threads.create_thread(fThreads[i]->find()); } threads.join_all(); As you can see from the code above, I have an array of FileThread objects, which have several functions. What I want to do, is to first off invoke the find() function which will go through some algorthms (this is already done) and then the print() function which will print the results. How can I invoke the print() function with the same thread ?
Shaolin wrote:
Hi Guys
I am trying to convert my application to a multithreaded app. Please see code below:
boost::thread_group threads; FileThread *fThreads[filearr.size()];
for(int i=0; i < filearr.size(); i++) { fThreads[i] = new FileThread(filearr[i]); threads.create_thread(fThreads[i]->find()); } threads.join_all();
As you can see from the code above, I have an array of FileThread objects, which have several functions. What I want to do, is to first off invoke the find() function which will go through some algorthms (this is already done) and then the print() function which will print the results. How can I invoke the print() function with the same thread ?
Shaolin -
Boost.Thread is going to invoke a functor or function of some sort that
takes no arguments. As a result you need make the function or functor you
want called fit that signature. Often bind is used for this. You want to call
multiple statements. A simple way is to create a helper object of some sort.
For example, you could create a structure like this (untested):
struct my_helper
{
my_helper( FileThread* object ) : object_( object ){}
void operator()() { object_->find(); object_->print(); }
};
.... then in your create_thread call....
threads.create_thread( my_helper( fThreads[ i ] ) );
Another option would be to create the "my_helper" function inline using
a lambda function. You can do this with a library such as Boost.Phoenix.
The following little example illustrates Phoenix's Block Statement or
ability to have a sequence of statements. I also took the liberty to
use shared_ptr for reference counting and a vector instead of a vanilla
array.
Hopefully this is useful.
----------------------------------------------------------
#include <vector>
#include <iostream>
#include
Thanks for the reply Michael. The first example looks easier to digest. I
have a question, what exactly does the following piece of code from the
struct do:
my_helper(FileThread* object) : object_( object ){}
I have seen it used once or twice before but cant find any documentation on
it.
2009/8/23 Michael Caisse
Shaolin wrote:
Hi Guys
I am trying to convert my application to a multithreaded app. Please see code below:
boost::thread_group threads; FileThread *fThreads[filearr.size()];
for(int i=0; i < filearr.size(); i++) { fThreads[i] = new FileThread(filearr[i]); threads.create_thread(fThreads[i]->find()); } threads.join_all();
As you can see from the code above, I have an array of FileThread objects, which have several functions. What I want to do, is to first off invoke the find() function which will go through some algorthms (this is already done) and then the print() function which will print the results. How can I invoke the print() function with the same thread ?
Shaolin -
Boost.Thread is going to invoke a functor or function of some sort that takes no arguments. As a result you need make the function or functor you want called fit that signature. Often bind is used for this. You want to call multiple statements. A simple way is to create a helper object of some sort. For example, you could create a structure like this (untested):
struct my_helper { my_helper( FileThread* object ) : object_( object ){}
void operator()() { object_->find(); object_->print(); } };
.... then in your create_thread call....
threads.create_thread( my_helper( fThreads[ i ] ) );
Another option would be to create the "my_helper" function inline using a lambda function. You can do this with a library such as Boost.Phoenix. The following little example illustrates Phoenix's Block Statement or ability to have a sequence of statements. I also took the liberty to use shared_ptr for reference counting and a vector instead of a vanilla array.
Hopefully this is useful.
----------------------------------------------------------
#include <vector> #include <iostream> #include
#include #include #include #include #include #include struct A { A( int id_ ) : id( id_ ) {} void foo(){ std::cout << "foo " << id << std::endl; } void bar(){ std::cout << "bar " << id << std::endl; }
int id; };
const int MAX_OBJECTS = 10;
int main() { using namespace boost::phoenix; using namespace boost::phoenix::local_names;
boost::thread_group my_threads; std::vector< boost::shared_ptr< A > > a_objects; for( int i=0; i
( new A( i ) ) ); my_threads.create_thread( let( _a = a_objects.back() ) [ bind( &A::foo, *_a ), bind( &A::bar, *_a ) ] ); }
my_threads.join_all();
return 0; }
----------------------------------------------------------------
Have I mentioned recently how much I like Phoenix? Awesome job Joel!
Michael
--
---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Shaolin wrote:
Thanks for the reply Michael. The first example looks easier to digest. I have a question, what exactly does the following piece of code from the struct do:
my_helper(FileThread* object) : object_( object ){}
I have seen it used once or twice before but cant find any documentation on it.
Shaolin - This is simply a constructor for the my_helper structure. It takes a pointer to a FileThread object. 'object_' is a member variable and it is being initialized in the initializer list of the constructor with 'object'. You may also want to look through a C++ tutorial. Regards - Michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
Shaolin wrote:
I have a question, what exactly does the following piece of code from the struct do:
my_helper(FileThread* object) : object_( object ){}
I have seen it used once or twice before but cant find any documentation on it. Look up "initialisation lists" (or "initialization lists" LOL).
Cheers, Brad
Thanks guys. Ok, I have been playing around and come up with the following
code:
struct my_helper
{
void run(string filenm, string searchtext) {
FileThread object(filenm, searchtext);
object.find();
object.print();
}
};
int main() {
boost::thread_group threads;
my_helper my;
threads.create_thread(boost::bind(&my::run, filearr[i], search));
}
The problem is the create_thread function returns the following error on
compile:
*error: ‘my’ is not a class or namespace
*
.
2009/8/23 Brad Hubbard
Shaolin wrote:
I have a question, what exactly does the following piece of code from the struct do:
my_helper(FileThread* object) : object_( object ){}
I have seen it used once or twice before but cant find any documentation on it.
Look up "initialisation lists" (or "initialization lists" LOL).
Cheers, Brad
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
That should be:
boost::bind(&my_helper::run, &my, filearr[i], search)
(for some definition of search)
In this case, bind is taking a pointer to the member function plus a
pointer to the object, followed by the arguments.
On Sun, Aug 23, 2009 at 8:53 AM, Shaolin
[...] int main() { boost::thread_group threads; my_helper my; threads.create_thread(boost::bind(&my::run, filearr[i], search)); }
The problem is the create_thread function returns the following error on compile:
error: ‘my’ is not a class or namespace
participants (4)
-
Brad Hubbard
-
Michael Caisse
-
Oliver Seiler
-
Shaolin