Boost logo

Boost Users :

From: Delfin Rojas (drojas_at_[hidden])
Date: 2008-02-11 02:46:03


> Paul J R wrote:
>
> mytest.cpp:
>
> class A {
> public:
> A() {}
> ~A() {}
> virtual void worker() {
> std::cout << "I am A worker" << std::endl;
> }
> virtual A *factory() {
> std::cout << "Factory for A class called" <<
std::endl;
> return new A;
> }
> virtual void operator()() {
> std::cout << "Calling A operator()" << std::endl;
> worker();
> }
> void threadcontroller() {
> boost::thread_group thre;
> for(;;) {
> std::cout << "I am in the A.threadcontroller()
> method" << std::endl;
> A *mea = factory();
> mea->worker();
> thre.create_thread(*mea);
> exit(0);
> }
> }
> };
>
> class B: public A {
> public:
> B() {}
> ~B() {}
> virtual void worker() {
> std::cout << "I am B worker" << std::endl;
> }
> virtual void operator()() {
> std::cout << "Calling B operator()" << std::endl;
> worker();
> }
> B *factory() {
> std::cout << "Factory for B class called" <<
std::endl;
> return new B;
> }
> };
>
> int main()
> {
> B meb;
>
> meb.worker();
> meb.threadcontroller();
> }
>

Hi Paul,

Note that thread_group::create_thread(const boost::function0<void>&)
takes a boost::function0<void> as an argument so in case you pass a
functor like you do, boost::function will resolve to the operator() of
the apparent pointer type (i.e. A::operator()). In order to make this
work you need a way to construct a "pointer to member function" which
takes into account the actual value of "this".

So instead of

thre.create_thread(*mea);

You want:

thre.create_thread(boost::bind(&A::operator(), mea));

For this you need to include boost/bind.hpp. In this case boost::bind
will make a functor and when create_thread calls that functor,
boost::bind will effectively call mea->operator().

Next thing, you don't want to call exit() right after you create the
thread because once your main thread exits the other one will exit too
(how soon depends on your OS, in my machine the thread doesn't even get
to start before it is killed because the main thread is exiting). So you
want to call thre.join_all(); so the main thread sleeps until all the
threads are done. So my A::threadcontroller looks like this:

void threadcontroller() {
        boost::thread_group thre;
      std::cout << "I am in the A.threadcontroller() method" <<
std::endl;
      A *mea = factory();
      mea->worker();
      thre.create_thread(boost::bind(&A::operator(), mea));
      thre.join_all();
}

Using this A::threadcontroller my output looks like this:

I am B worker
I am in the A.threadcontroller() method
Factory for B class called
I am B worker
Calling B operator()
I am B worker

Which is what you want (I think).

Also, one nice thing about using boost::bind is that you can use any
method as the thread body (i.e. you can rename your operator() to
dowork() if you want).

Good luck,

-delfin


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