C++ 这样的类在多个线程的集合中只能读取一次吗?
所以有一门课,比如:C++ 这样的类在多个线程的集合中只能读取一次吗?,c++,multithreading,oop,boost,locking,C++,Multithreading,Oop,Boost,Locking,所以有一门课,比如: 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.notif
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
的线程实际获取数据(每个线程只需调用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;
};
我认为您不需要条件变量;互斥应该足够了
而且,
已更改的
变量对您没有帮助;它只允许一个线程看到更改。也删除它。我认为您不需要条件变量;互斥应该足够了
而且,
已更改的
变量对您没有帮助;它只允许一个线程看到更改。也删除它。实际上,在阅读器中调用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
的调用将有效地等待状态的有效更改。然而,这种方法(有条件的)容易出现诸如虚假唤醒(应该由循环处理)、丢失通知等问题。您需要为此找到更好的模型(所有这些听起来都像是每个线程都有一个队列)。实际上,在读卡器(Get
)中调用notify_one()
是一种奇怪的方法!如果您想让读者等待某项设置完成,那么您需要以下内容:
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
的调用将有效地等待状态的有效更改。但是,这种方法(有条件)容易出现诸如虚假唤醒(应由循环处理)、丢失通知等问题。您需要找到一个更好的模型(所有大多数听起来都像是每个线程都有一个队列)。I updated post-您的意思是我发布的更新可以工作吗?我的主要观点是让读者不要在一个集合上阅读超过一次…我想这是可行的(尽管您可能需要将myData
声明为volatile
,以防止编译器进行不安全的优化。我不确定您所说的“在每个集合上阅读不超过一次”是什么意思。您肯定只想get()
每次读线程调用时安全返回最新值?我试图在这里解释我更新了帖子-你的意思是我发布的更新会起作用吗?我的要点是,读者不要在一个集合上阅读超过一次…我想这会起作用(虽然您可能需要将myData
声明为volatile
,以防止编译器进行不安全的优化。我不确定您所说的“每次读取不超过一次”是什么意思。您肯定只想get()
要在每次读卡器线程调用时安全地返回最近的值,我尝试在这里进行解释