我有这样的信息集合:
std::list< boost::shared_ptr<DataEntry> > m_Entries;
该列表由多个线程访问。大多数情况下只读取列表,但有时线程需要添加或删除列表中的条目。因此,列表本身受读取器/写入器锁保护,但条目不是。
单个条目本身大部分是不可变的(一些很少访问的可变成员被单独锁定以防止并发问题),并且shared_ptr
用于确保在线程读取时不删除条目它,即使另一个线程从列表中删除了该条目。
访问的本质是,给定的线程通常会重复访问一个特定的条目,偶尔访问另一个(变化的)条目。数据是否过时并不重要,只要它在使用时不会被删除。目前,每次需要输入时,都必须获取锁,搜索列表,复制shared_ptr
,然后释放锁。没有地方线程可以在访问之间存储指针;它必须每次都释放并重新获取。
因此,我认为通过在线程本地存储中缓存最常用的条目(作为shared_ptr
或weak_ptr
)可以获得性能优势,以避免必须获取锁定所有这些都是最常见的情况。
不幸的是,我正在使用VS2008,而它的__declspec(thread)
不支持非POD类型,例如智能指针。我无法存储裸指针,因为这不会提供我需要的非删除保证。我想我可以存储一个weak_ptr*
,但这会导致线程退出时泄漏内存(和弱引用计数)(虽然我确实有一个在“正常”线程退出时调用的钩子,所以这可以减轻一个位)。而且出于明显的原因,存储shared_ptr*
会更加糟糕。
考虑到复杂性,并且锁通常是无竞争的,我不确定可能边际的性能提升值得麻烦。但我想知道我是否错过了更好的方法。 (如果C ++ 11中的内容有所改进,我也很好奇,因为它有更好的线程支持。)