通过线程本地存储访问shared_ptr

时间:2012-02-14 02:17:22

标签: c++ multithreading shared-ptr smart-pointers thread-local

我有这样的信息集合:

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中的内容有所改进,我也很好奇,因为它有更好的线程支持。)

1 个答案:

答案 0 :(得分:0)

尝试Boost的Thread Local Storage - 我很乐观它可能适用于你的VS 2008编译器。