0

我似乎在同步数据收集时遇到问题。在这个特定的类中,我有一个数据集合、互斥体和条件变量,看起来像:

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();

发生的事情是,当我的“写”函数被调用时,它似乎死锁了一段时间。它最终会打破它,所以它不是一个完整的死锁,但等待时间可能很长(几秒钟)。这应该是毫秒或更短的时间。

奇怪的是,我之前已经成功使用过上面的 writer 函数,并且有多个线程毫无问题地写入这个数据集合。我进行此更改的原因是将对该集合的更新集中到一个地方,而不是让它依赖于其他线程的运行时状态。

4

1 回答 1

2

感谢对我的问题的评论,我最终做了几件事:

  1. 在读取函数中停止使用 operator[] 并将读取函数设为 const。

  2. 停止使用 condition_variable

  3. 根据其他帖子中的示例使用 shared_mutex 。

编码:

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;
}
于 2013-06-12T18:19:54.483 回答