通过线程本地存储访问shared_ptr

Accessing shared_ptr via thread local storage

本文关键字:访问 shared ptr 存储 线程      更新时间:2023-10-16

我收集了这样的信息:

std::list< boost::shared_ptr<DataEntry> > m_Entries;

该列表可由多个线程访问。大多数情况下,只读取列表,但偶尔线程需要添加或删除列表中的条目。因此,列表本身受读写器锁保护,但条目不受保护。

单个条目本身大多是不可变的(少数很少访问的可变成员被单独锁定以防止并发问题),shared_ptr用于确保在线程读取条目时不会删除条目,即使另一个线程从列表中删除了该条目。

访问的性质是,给定线程通常会重复访问一个特定条目,偶尔还会访问另一个(变化的)条目。数据是否陈旧并不重要,只要在使用中没有删除即可。目前,每当它需要一个条目时,它都必须获取锁,搜索列表,复制shared_ptr,然后释放锁。线程无法在访问之间存储指针;它每次都必须释放和重新获取。

因此,我认为在线程本地存储中缓存最常用的条目(作为shared_ptrweak_ptr)可能会带来性能优势,从而避免在最常见的情况下必须获取锁。

不幸的是,我使用的是VS2008,它的__declspec(thread)不支持非POD类型,例如智能指针。我不能存储裸指针,因为这不会提供我需要的不删除保证。我想我可以存储一个weak_ptr*,但这会导致线程退出时内存泄漏(和引用计数不足)(尽管我确实有一个钩子在"正常"线程退出时被调用,所以这可以稍微减轻一点)。出于显而易见的原因,存储shared_ptr*可能会更糟。

考虑到锁的复杂性,而且锁通常是不受控制的,我不确定这种可能微不足道的性能提升是否值得这么麻烦。但我想知道我是否错过了更好的方法。(我也很好奇C++11中的情况是否有所改善,因为它有更好的线程支持。)

试试Boost的线程本地存储-我很乐观它可能与您的VS2008编译器一起工作。