清除锁定下的std :: map与移动到临时对象

kwa*_*hwa 8 c++ multithreading mutex stdmap c++14

我正在使用std :: map并且其中包含大量元素.如果我需要清除地图,我可以在上面调用clear().它可能需要一些时间来清除,特别是如果在多线程环境中的锁定下完成,它可以阻止其他调用.为了避免调用clear(),我尝试了这个:

std::mutex m;
std::map<int, int> my_map; // the map which I want to clear

void func()
{
    std::map<int, int> temp_map;
    {
        std::lock_guard<std::mutex> l(m);
        temp_map = std::move(my_map);
    }
}
Run Code Online (Sandbox Code Playgroud)

这会将my_map移动到锁定下的temp_map,这会将其清空.然后一旦func结束,temp_map将被销毁.

这是一个更好的方法来防止锁定很长一段时间吗?是否有任何表演命中?

rod*_*igo 5

我建议使用swap而不是move.移动的对象不能保证实际为空或甚至可用.但是,使用swap和新创建的对象,您可以确定结果:

void func()
{
    std::map<int, int> temp_map;
    using std::swap;
    {
        std::lock_guard<std::mutex> l(m);
        swap(my_map, temp_map);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • *"移动的物体不能保证实际上是空的,甚至不可用."*标准在此不同意.[lib.types.movedfrom]:*"C++标准库中定义的类型的对象可以从(12.8)移动.可以显式指定或隐式生成移动操作.除非另有说明,否则应将这些移动的对象放入a**有效但未指定的状态**."*(强调我的.)所以`my_map.clear();`足以将移动的地图返回到已知(和空)状态.但是+1仍然因为交换更干净. (3认同)
  • @ K.Wadhwa:您可能是指问题评论中的链接......我认为这是错误的(我在上面回答).TL; DR; `a = move(b)`在`a`的大小上是线性的,在你的情况下是空映射. (2认同)