C ++ map.erase()会导致不必要的平衡

时间:2012-01-13 20:07:52

标签: c++ multithreading map segmentation-fault

我有一个map<uint, Order*> orders,其中Order是一个定义的类,其中包含id,时间,价格和数量等适用字段。我还有一个线程,它监听下面定义的地图的传入订单添加和删除。

void System::OrderDeleted_Thread(unsigned int order_id)
{
    if(orders.find(order_id) != orders.end())
    {
            Order* order = orders[order_id];
            orders.erase(order_id);
            delete order;
    }
}

我的问题与此非常相似:

Segmentation fault in std function std::_Rb_tree_rebalance_for_erase ()

我的问题是,在重新平衡树时,如何在没有程序给出错误的情况下迭代我的订单地图?就像链接中的解决方案所说的那样,我已经取出了.erase(uint)方法并让它发挥作用。不幸的是,我无法保存数万个键的地图。

提前致谢!

3 个答案:

答案 0 :(得分:4)

  

我还有一个线程,它监听下面定义的地图的传入订单添加和删除。

您需要同步对地图的访问权限。 STL容器不具有多个编写器的线程安全性(并且擦除元素正在写入容器),而没有某种外部同步。

答案 1 :(得分:1)

在单独的数据结构中对您的添加和删除进行排队,然后在安全的时间处理它们,即保证您不会迭代地图。安全时间可以在您获得保护地图的互斥锁之后,或者其他方式,具体取决于您的程序。

答案 2 :(得分:0)

除了同步问题,这是编写循环的一种昂贵的方法。相反,试试这个:

std::map<uint, Order*>::iterator it;
Order * p = NULL;

{ // enter critical section
    if ((it = orders.find(id)) != orders.end())
    {
        p = it->second;
        orders.erase(it);
    }
} // leave critical section

delete p;