一位作家很多读者为地图问题

时间:2013-06-11 20:50:00

标签: c++ multithreading boost boost-mutex

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

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

发生的事情是,当我的'write'函数被调用时,它似乎会陷入僵局一段时间。它最终突破它,所以它不是完全的死锁,但等待时间可能很长(几秒钟)。这应该是毫秒级或更短的时间。

奇怪的是,我之前已成功使用上述编写器函数,并且有多个线程写入此数据集合而没有问题。我进行此更改的原因是将此集合的更新集中到一个位置,而不是依赖于其他线程的运行时状态。

1 个答案:

答案 0 :(得分:2)

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

  1. 在read函数中停止使用operator []并使read函数成为常量。

  2. 停止使用condition_variable

  3. 根据示例in this other post.

  4. 使用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;
    }