разблокировка потоков только по новым данным (порядок вызова потоков) - PullRequest
0 голосов
/ 17 января 2011

так что у меня есть класс, как:

class mySafeData
{
public:
    void Set(int i) {
        boost::mutex::scoped_lock lock(myMutex);
        myData = i;
    }
    void Get( int& i)
    {
        boost::mutex::scoped_lock lock(myMutex);
        i = myData;
    }
private:
    int myData;
    boost::mutex myMutex;

};

У меня есть какой-то поток, который вызывает Set в цикле, и 3 потока, которые вызывают Get в цикле. Мне нужно сделать мои потоки Get одним набором данных не более одного раза (то есть он не может вызывать Get так же быстро, как мы Set, и это нормально, но он не должен вызывать его более одного раза, пока не появится новый Set был назван). Я имею в виду, что после потока с именем Get он не получит доступа к Get unteel Set. Как внедрить такую ​​вещь в такой простой класс или моя блокировка сделает это для меня по умолчанию?

Ответы [ 2 ]

2 голосов
/ 17 января 2011

Вам нужна переменная условия .

Обратите внимание, что даже когда ваш поток чтения получает мьютекс, связанный с условной переменной, он должен проверить, что условие выполнено. Возможно, пусть установщик установит флаг, когда он что-то установил, и читатель сможет сбросить его, когда прочтет.

Это нуждается в уточнении, но сделает работу. Я бы обычно использовал std :: deque, чтобы писатель мог написать, что нужно заблокировать, но не нужно ждать, пока поток прочитает.

class mySafeData
{
public:
  mySafeData() : myData(0), changed( false )
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    while( changed )
        myCondvar.wait( lock ); // wait for the data to be read

    myData = i; // set the data
    changed = true; // mark as changed
    myCondvar.notify_one(); // notify so a reader can process it
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    while( !changed )
    {
       myCondvar.wait( lock );
    } 
    i = myData;
    changed = false; // mark as read
    myCondvar.notify_one(); // notify so the writer can write if necessary
  }
 private:
   int myData;
   boost::mutex myMutex;
   boost::condition_variable myCondvar;
   bool changed;
};
1 голос
/ 17 января 2011

Вам необходимо использовать условную переменную , чтобы сообщить об изменении состояния объекта другим потокам.

...