доступ к переменной-члену объекта потока Boost - PullRequest
4 голосов
/ 24 февраля 2009

Я использую объект для запуска буст-потока, и у него есть некоторые открытые переменные-члены, которые я изменяю в потоке (в операторе ()). Как я могу получить доступ к переменным-членам объекта извне потока?

Я попытался использовать мьютекс (определенный в классе объекта), который заблокирован как в операторе () объекта, так и снаружи, но, похоже, он не работает.

Вот код объекта потока:

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;
    }
      }
  }
};

И здесь я пытаюсь получить доступ к переменным x и y мыши:

  {
    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

Ответы [ 2 ]

10 голосов
/ 24 февраля 2009

boost::thread копирует переданную функцию потока во внутреннее хранилище, поэтому если вы запустите свой поток следующим образом, поток будет работать с другой копией 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
  ...
}

Вы можете использовать boost::ref для передачи ссылки на существующий объект:

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

В этом случае thr изменит глобальный объект mouse, но вы должны убедиться, что mouse не выйдет из области видимости или будет уничтожен в противном случае до завершения thr.

0 голосов
/ 24 февраля 2009

ОК, теперь я вижу это яснее. Несколько советов, глядя на ваш код:

  1. Не выставлять внутренние мьютексы.
  2. Операции доступа записи, которые блокируют и разблокируют мьютекс. Таким образом, вам не нужно передавать пользователю вашего класса эффективную блокировку (и разблокировку) мьютекса.
  3. Считать данные из файла до потока. Возможно, чтение блокируется или слишком медленно для другого потока, чтобы получить данные. Если вы прочитали данные раньше, а затем запустили поток, все данные были бы прочитаны к тому времени, когда клиенты получат доступ к данным потока.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...