Rella
Rella

Reputation: 66965

unlocking threads only on new data (threads calling order)

so i have a class like:

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;

};

I have some thread that calls Set in loop and 3 threads that call Get in a loop. I need to make my threads Get one peace of data not more than once (meaning it can not call Get as fast as we Set it and that is OK but it shall not call it more than once unteel new Set was called). I mean after thread called Get it shall not gain access to Get unteel Set was executed. How to implement such thing into such simple class or will my lock do it for me by default?

Upvotes: 0

Views: 95

Answers (2)

CashCow
CashCow

Reputation: 31445

You need a condition variable.

Note that even when your reader thread acquires the mutex associated with condition variable, it needs to check the condition has been met. Perhaps let the setter set a flag when it has set something and the reader can reset it when it has read it.

This needs refinement but will do the job. I would generally use a std::deque so the writer can write having to lock but without having to wait for a thread to read it.

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

Upvotes: 2

wilx
wilx

Reputation: 18238

You need to use conditional variable to signal the change in state of the object to the other threads.

Upvotes: 1

Related Questions