views:

534

answers:

3

I'm using an object to start boost thread and it has some public member variables which I modify in the thread (in the () operator). How can I access the object's member variables from outside the thread?

I tried using a mutex (defined in the object's class) that is locked both in the operator() of the object and from outside, but it doesn't seem to work.

Here's the thread object code:

struct Mouse
{
  int x, y;
  string port;

  boost::mutex mutex;

  Mouse(const string& p) : port(p) { x = y = 0; }
  Mouse(const Mouse& m) : mutex() { x = m.x; y = m.y; port = m.port; }

  void operator()()  
  {
    ifstream ifs;
    ifs.open (port.c_str(), ios::binary );
    if (!ifs.is_open())
    {
      cout << "Impossible d'ouvrir " << port.c_str() << "\n";
      exit(0);
    }
    while (true) //modify x, y in infinit loop
      {
    char buf[3];
    ifs.read(buf, 3);
        unsigned char * msg = (unsigned char *) buf;
    unsigned char xsign = (msg[0]>>4) & 1;
    unsigned char ysign = (msg[0]>>5) & 1;
        unsigned char always1 = (msg[0]>>3) & 1;
    short dx = msg[1] - 256*xsign;
    short dy = msg[2] - 256*ysign;
    {
      boost::mutex::scoped_lock lock(mutex);
      x += abs(dx);
      y += dy;
    }
      }
  }
};

And this is where I try to access the x and y variables of the mouse:

  {
    boost::mutex::scoped_lock leftlock(leftMouse.mutex);
    xLeft = leftMouse.x;
    yLeft = leftMouse.y;
  }
  {
    boost::mutex::scoped_lock rightlock(rightMouse.mutex);
    xRight = rightMouse.x;
    yRight = rightMouse.y;
  }
  cout << xRight << " " << yRight << endl;  //this always prints 0 0
A: 
struct foo
{
    void operator()()
    {
        // do stuff
    }
    int bar;
};

foo f;

int main()
{

    boost::thread thrd1(boost::ref(f));
    thrd1.join();
    std::cout << f.bar << std::endl;
}

I'm not sure whether I understood correctly what you want to achieve, but is it something along these lines (the point of using boost::ref() )? You didn't show us the code how you start the thread and how you want to access the object.

Anonymous
A: 

OK, now I see it clearer. Some advice looking at your code:

  1. Don't expose internal mutexes.
  2. Write access operations that lock and unlock the mutex. This way you don't have to relay on the user of your class to effectively locking (and unlocking) the mutex.
  3. Read the data from the file before the thread. Probably the read is blocking, or it is too slow for the other thread to obtain the data. If you read the data before, and then start the thread, all the data would be read by the time clients access to the data of the thread.
Diego Sevilla
+8  A: 

boost::thread copies the passed thread function to internal storage, so if you start your thread like this, the thread will operate on a different copy of mouse:

int main() {
  Mouse mouse("abc.txt");
  boost::thread thr(mouse); // thr gets a copy of mouse
  ...
  // thread changes it's own copy of mouse
  ...
}

You can use boost::ref to pass a reference to an existing object instead:

  Mouse mouse("abc.txt");
  boost::thread thr(boost::ref(mouse)); // thr gets a reference of mouse

In this case thr will modify the global mouse object, but you have to make sure that mouse doesn't go out of scope or gets destroyed otherwise before thr is finished.

sth