Would such class be readable only once a Set by mu

2019-08-03 00:25发布

问题:

So having a class like:

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

And one thread in loop calling Set. And 3 or more threads calling Get how to make all threads calling Get to actually get data (each thread shall Get data only once a Set was called)(it seems like only first "reader" who calls Get gets data)?

update will this do?:

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

回答1:

Actually, It's an odd approach to call notify_one() in the reader (Get)! If you want your readers to wait till something has been set, then you need something like this:

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

Now a call to Get will effectively wait till there is a valid change of state. However this approach (with conditions) is prone to issues such as spurious wakeups (which should be handled by the loop), lost notifications etc. You need to find a better model for this (all most sounds like a case of a queue per thread).



回答2:

I don't think you need the condition variable; the mutex ought to be enough.

Also, the changed variable isn't helping you; it's only allowing one thread to see the change. Remove that as well.