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