Reputation: 66965
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
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
Reputation: 18238
You need to use conditional variable to signal the change in state of the object to the other threads.
Upvotes: 1