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

C++ map.erase() causes unwanted balancing

本文关键字:不必要 平衡 esers C++map      更新时间:2023-10-16

我有一个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;
    }
}

我的问题与此非常相似:

std函数std::_Rb_tree_rebalance_for_erase()中的分段错误

我的问题是,当需要重新平衡树时,如何在程序不给我错误的情况下迭代订单图?就像链接中的解决方案所说的那样,我已经去掉了.erase(uint)方法并使其发挥作用。不幸的是,我无法随身携带数万把钥匙的地图。

提前感谢!

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

您需要同步对地图的访问。STL容器在没有某种外部同步的情况下,对于多个写入程序(擦除元素就是写入容器)是不线程安全的。

在一个单独的数据结构中对您的添加和删除进行排队,然后在安全的时间进行处理,即保证您不会在映射中迭代。这个安全时间可以是在您获取了保护映射的互斥对象之后,也可以是其他方式,具体取决于您的程序。

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

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;