Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

accessing member variable of boost thread object

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
like image 616
Al. Avatar asked Dec 30 '22 04:12

Al.


1 Answers

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.

like image 173
sth Avatar answered Jan 01 '23 19:01

sth