boost threads return type operator()

Discussion in 'C++' started by Chris Roth, Apr 18, 2007.

  1. Chris Roth

    Chris Roth Guest

    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.
     
    Chris Roth, Apr 18, 2007
    #1
    1. Advertising

  2. Chris Roth

    James Kanze Guest

    Chris Roth wrote:
    > 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).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 19, 2007
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Richard Latter
    Replies:
    2
    Views:
    2,917
    Julie
    May 17, 2004
  2. Steve Knight
    Replies:
    2
    Views:
    779
    Steve Knight
    Oct 10, 2003
  3. Toby Bradshaw
    Replies:
    6
    Views:
    1,780
    Kai-Uwe Bux
    Jun 2, 2006
  4. Martin T.
    Replies:
    7
    Views:
    825
    Martin T.
    Mar 10, 2008
  5. Replies:
    5
    Views:
    529
    Bart van Ingen Schenau
    Jun 23, 2009
Loading...

Share This Page