安全销毁包含shared_ptr的地图

时间:2013-03-11 16:52:08

标签: c++ multithreading c++11

我正在阅读Mir project源代码,我偶然发现了这段代码:

void mir::frontend::ResourceCache::free_resource(google::protobuf::Message* key)
{
    std::shared_ptr<void> value;
    {
        std::lock_guard<std::mutex> lock(guard);

        auto const& p = resources.find(key);

        if (p != resources.end())
        {
            value = p->second;
        }

        resources.erase(key);
    }
}

我之前在其他项目中也见过这个。它在擦除之前对地图中的值进行引用,即使该集团受到lock_guard的保护。我不确定为什么他们使用 std :: shared_ptr值来引用该值。

如果我们删除值= p-&gt;秒会有什么影响?

有人请赐教我吗?

这是代码http://bazaar.launchpad.net/~mir-team/mir/trunk/view/head:/src/frontend/resource_cache.cpp

2 个答案:

答案 0 :(得分:3)

我猜这是为了避免在锁定的代码中运行value的析构函数。这个锁用于保护地图的修改,并且不需要也不需要运行一些任意代码,例如锁定它的另一个对象的析构函数。

想象一下,value的析构函数无论出于什么原因间接访问地图,或者访问另一个线程共享结构。你有可能陷入僵局。

底端是:从锁定的代码中尽可能少地运行代码,但不能少。永远不要从锁定的代码中调用外部的,未知的函数(例如shared_ptr删除或回调)。

答案 1 :(得分:2)

目标是移动shared_ptr删除器的实际执行,直到锁定被释放。这样,如果删除器(或使用默认删除器的析构函数)需要很长时间,则不会为该操作保持锁定。

如果要删除value = p->second,则在保持锁定时将销毁该值。由于锁可以保护地图,但不保护实际值,因此锁定的时间会比严格必要的时间长。