Boost logo

Boost Users :

Subject: Re: [Boost-users] Invoke several functions with the same thread
From: Michael Caisse (boost_at_[hidden])
Date: 2009-08-22 19:29:43


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 <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/spirit/home/phoenix/core.hpp>
#include <boost/spirit/home/phoenix/scope.hpp>
#include <boost/spirit/home/phoenix/statement/sequence.hpp>
#include <boost/spirit/home/phoenix/operator.hpp>
#include <boost/spirit/home/phoenix/bind/bind_member_function.hpp>

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<MAX_OBJECTS; ++i )
   {
      a_objects.push_back( boost::shared_ptr< A >( 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 list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net