将这样的类是可读的一次一组由多个线程?(Would such class be readable o

2019-09-28 19:35发布

因此,有喜欢的一类:

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

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    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;
};

而在环路中的一个线程调用Set 。 和3级或更多的线程调用Get如何让所有线程调用Get实际得到的数据(每个线程将Get的数据只开一次Set叫)(这似乎是唯一的第一“读者”谁调用Get获取数据)?

更新将这个做?:

class mySafeData
{
public:
  mySafeData() : myData(0)
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    i = myData;

  }
 private:
   int myData;
   boost::mutex myMutex;
};

Answer 1:

其实,这是一个奇怪的方法来调用notify_one()在读卡器( Get )! 如果你希望你的读者等到事情已定,那么你需要的东西是这样的:

 void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
    ++stateCounter;  // some int to track state chages
    myCondvar.notify_all(); // notify all readers
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    // copy the current state
    int cState = stateCounter;
    // waits for a notification and change of state
    while (stateCounter == cState)
      myCondvar.wait( lock );
  }

现在调用Get将有效地等待,直到有状态的有效转变。 但是这种方法(附带条件)很容易出现诸如虚假唤醒(这应该由循环处理),丢失通知等问题,你需要找到这个更好的模式(所有最听起来像是每个线程队列的情况下, )。



Answer 2:

我不认为你需要的条件变量; 互斥应该足够了。

此外, changed变量没有帮助你; 它是只允许一个线程看到的变化。 删除这一点。



文章来源: Would such class be readable only once a Set by multiple threads?