所以有一个类:
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;
};
答案 0 :(得分:3)
我认为你不需要条件变量;互斥量应该足够了。
此外,changed
变量对您没有帮助;它只允许一个线程看到变化。删除它。
答案 1 :(得分: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
的调用将有效地等待状态发生有效更改。然而,这种方法(有条件)容易出现诸如虚假唤醒(应该由循环处理),丢失通知等问题。你需要找到一个更好的模型(所有大多数声音就像每个线程的队列一样) )。