boost threads return type operator()

C

Chris Roth

I've been working with boost::threads to do some multithreading in my
code and have run into some questions that I haven't been able to find
answers to.

I'll include some sample code to illustrate my questions.

#include <boost/thread/thread.hpp>
#include <iostream>

using namespace std;

class mt
{
private:
double _alpha;
double _beta;
double _x;
double& _y1;

public:
double _y2;

public:
mt( double alpha, double beta, double x, double& y1 ):
_alpha(alpha), _beta(beta),
_x(x), _y1(y1) {};

void operator()()
{
// Some function more complicated than this...
_y1 = _alpha/_beta*_x;
_y2 = _y1;
};

double GetY2() { return _y2; };
};

void main()
{
double y1;
double y2;
mt a( 4,1,3,y1 );
boost::thread thrd( a );
thrd.join();
y2 = a.GetY2();
cout << y1 << endl;
cout << y2 << endl;
}

If I understand everything correctly, when I call
boost::thread thrd( a ),
it creates a new (thread local) instance of mt with which to work with
which goes out of scope at
thrd.join(). That is why y1 gives a good answer, but y2 contains garbage.

Now for my question:

Is it possible to call something like:
y = boost::thread thrd( a(x) );
where I've redefines operator() to take a double "x"
and return a double "y".
Then I don't have to give x and y when I construct "a".

Basically, my question is how to return something from the () operator
inside the thread.

Please ask for clarification if I haven't been clear.
 
J

James Kanze

Chris said:
I've been working with boost::threads to do some multithreading in my
code and have run into some questions that I haven't been able to find
answers to.
I'll include some sample code to illustrate my questions.
#include <boost/thread/thread.hpp>
#include <iostream>
using namespace std;
class mt
{
private:
double _alpha;
double _beta;
double _x;
double& _y1;

public:
double _y2;

public:
mt( double alpha, double beta, double x, double& y1 ):
_alpha(alpha), _beta(beta),
_x(x), _y1(y1) {};
void operator()()
{
// Some function more complicated than this...
_y1 = _alpha/_beta*_x;
_y2 = _y1;
};
double GetY2() { return _y2; };
};
void main()

Just a nit, but should be "int".
{
double y1;
double y2;
mt a( 4,1,3,y1 );
boost::thread thrd( a );
thrd.join();
y2 = a.GetY2();
cout << y1 << endl;
cout << y2 << endl;
}
If I understand everything correctly, when I call
boost::thread thrd( a ),
it creates a new (thread local) instance of mt with which to work with
which goes out of scope at
thrd.join().

Not quite. It doesn't go out of scope until you leave main.
All the join does is block the calling thread until the other
thread finishes.
That is why y1 gives a good answer, but y2 contains garbage.

No. You're overlooking the fact that the new thread is started
with a *copy* of your functional object. (Think of what would
happen otherwise if your functional object were a temporary,
which is often the case.) y1 has a good value because the
functional object contained a reference; all of the copies use
the same actual variable. y2 contains garbage because it was
never initialized in the original object; the child thread wrote
to a copy.

In general, the functional object should use only references or
pointers for out and inout values. If you change _y2 to a
reference in your class mt, you can then write:

double y1 ;
double y2 ;
boost::thread thrd( mt( 4, 1, 3, y1, y2 ) ) ;
// Obviously, you have to initialize the
// reference...
// Note that any use of y1 or y2 here is undefined
// behavior.
thrd.join() ;
std::cout << y1 << std::endl ;
std::cout << y2 << std::endl ;
Now for my question:
Is it possible to call something like:
y = boost::thread thrd( a(x) );
where I've redefines operator() to take a double "x"
and return a double "y".
Then I don't have to give x and y when I construct "a".

No. boost::thread always treats the functional object as
returning void.
Basically, my question is how to return something from the () operator
inside the thread.

You can't, per se. Boost.threads makes no provision for return
values or exceptions. On the other hand, it probably wouldn't be
too difficult to create a wrapper which would allow it (return
values, that is; exceptions would be considerably harder).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top