我似乎在同步数据收集时遇到了问题。在这个特定的类中,我有一个数据集合、互斥锁和条件变量,看起来像这样:
map<std::string, double> collection;
boost::mutex collectionMutex;
boost::condition_variable collectionConditional;
在大多数情况下,这是可行的。但是,最近我添加了一个函数,我基本上为集合中的每个值分配了一个新值。集合中大约有 100-200 个值,所以不是很多;所有的任务都发生得非常快。我还确保在此步骤中不会发生任何计算,它只是一系列作业。在作业周围,我的代码看起来像这样(基于 stackoverflow 上的答案):
boost::mutex::scoped_lock lock(collectionMutex);
while(!lock.owns_lock())
{
collectionConditional.wait(lock);
}
// Assignments here
collectionConditional.notify_one();
在代码的其他地方,我有一个从集合中“读取”信息的函数,看起来像这样:
double result = 0;
boost::mutex::scoped_lock lock(collectionMutex);
while(!lock.owns_lock())
{
collectionConditional.wait(lock);
}
result = collection["Some String"];
collectionConditional.notify_one();
发生的事情是,当我的“写入”函数被调用时,它似乎会死锁一段时间。它最终打破了它,所以它不是一个完全的僵局,但等待时间可能很长(几秒钟)。这应该是几毫秒或更短的时间。
奇怪的是,我之前已经成功地使用了上面的写入器函数,并且有多个线程毫无问题地写入这个数据集合。我进行此更改的原因是将对此集合的更新集中到一个地方,而不是让它依赖于其他线程的运行时状态。
最佳答案
感谢对我的问题的评论,我最终做了几件事:
停止在读取函数中使用 operator[] 并将读取函数设为常量。
停止使用条件变量
根据示例使用了 shared_mutex in this other post.
代码:
map<std::string, double> collection;
mutable boost::shared_mutex collectionMutex;
...
//Write function:
void mapData()
{
// get upgradable access
boost::upgrade_lock<boost::shared_mutex> lock(collectionMutex);
// get exclusive access
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
// Assignments here. Eg:
// collection["Some String"] = 0.0;
}
// Read function:
double readData(std::string name) const
{
double result = 0;
boost::shared_lock<boost::shared_mutex> lock(collectionMutex);
map<std::string, double>::const_iterator it = collection.find(name);
if(it != data.end())
{
result = it->second;
}
return result;
}
关于c++ - 一个作家许多读者发行 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17053573/