我正在阅读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
答案 0 :(得分:3)
我猜这是为了避免在锁定的代码中运行value
的析构函数。这个锁用于保护地图的修改,并且不需要也不需要运行一些任意代码,例如锁定它的另一个对象的析构函数。
想象一下,value
的析构函数无论出于什么原因间接访问地图,或者访问另一个线程共享结构。你有可能陷入僵局。
底端是:从锁定的代码中尽可能少地运行代码,但不能少。永远不要从锁定的代码中调用外部的,未知的函数(例如shared_ptr
删除或回调)。
答案 1 :(得分:2)
目标是移动shared_ptr
删除器的实际执行,直到锁定被释放。这样,如果删除器(或使用默认删除器的析构函数)需要很长时间,则不会为该操作保持锁定。
如果要删除value = p->second
,则在保持锁定时将销毁该值。由于锁可以保护地图,但不保护实际值,因此锁定的时间会比严格必要的时间长。