2010-05-28 57 views
3

我的应用程序问题如下 -Boost shared_ptr use_count函数

我有一个大的结构foo。由于这些数据量很大,并且出于内存管理的原因,我们不希望在数据处理完成时将其删除。

我们将它们存储在std::vector<boost::shared_ptr<foo>>.

我的问题是有关知道什么时候所有的处理完成。第一个决定是我们不希望任何其他应用程序代码在结构中标记完整的标志,因为程序中有多个执行路径,我们无法预测哪一个是最后一个。

所以在我们的实现中,一旦处理完毕,我们删除的boost::shared_ptr<foo>>所有副本除了一个向量中。这会将shared_ptr中的引用计数器放到1.是否可以使用shared_ptr.use_count()来查看它是否等于1,以知道应用程序的所有其他部分何时完成数据。

一个额外的原因,我问的问题是,在共享指针shared_ptr升压文档建议不使用“use_count”为产品代码。


编辑 - 我没有说的是,当我们需要一个新的富,我们将扫描foo的指针寻找一个foo的载体,其是当前未使用和使用FOO下一轮的处理。这就是为什么我认为使用1的引用计数器是确保这个特定foo对象不再被使用的安全方法。

+0

你的代码是多线程的吗?如果是的话,这将改变答案。 – wheaties 2010-05-28 14:01:01

+0

是的,有3到6个线程处理数据 – 2010-05-28 14:09:28

回答

4

我的直接反应(我得承认,它没有比这更)是,它听起来就像你想获得某种形式的池分配器的效果。你可能会更好地超载operator newoperator delete以更直接地获得你想要的效果。有了这样的事情,你可以像平常一样使用shared_ptr,而你想延迟的其他工作,将在该类的operator delete中处理。

这留下了一个更基本的问题:你真的想用这个完成什么?从内存管理的角度来看,一个共同的愿望是一次为大量对象分配内存,在整个块为空之后,立即释放整个块。如果您正在尝试按照该顺序进行操作,那么通过超载newdelete比通过玩shared_ptruse_count来实现几乎肯定更容易。

编辑:根据您的评论,超载newdelete类听起来像是正确的事情。如果有的话,集成到您现有的代码可能会更容易;事实上,你通常可以完全透明地做到这一点。

分配器的一般想法与您在编辑的问题中概述的几乎相同:有一个结构(位图和链表都是常见的)来跟踪您的自由对象。当new需要分配一个对象时,它可以扫描位向量或查看自由对象链表的头部并返回其地址。

这是链接列表可以很好地工作的一种情况 - 您(通常)不必担心内存使用情况,因为您将链接存储在空闲对象中,并且(几乎)不会有走这个列表,因为当你需要分配一个对象时,你只需要抓取列表中的第一个项目。

这类事情在小物件中特别常见,因此您可能要查看关于其小对象分配器的章节(以及自Andrei Alexandrescu关于他的新概念之后的一两篇文章如何做这种事情)。还有Boost :: pool分配器,它通常至少有点类似。

+0

您已经总结了我的问题。我们试图将它作为我们可以从中获得下一个免费的对象的对象池。 无论我们做什么,我们也必须看看我们是否也可以将其改装到我们现有的代码库以及我们的新应用程序。 – 2010-05-28 14:08:24

0

我建议,而不是试图使用的shared_ptr的use_count跟踪,它可能是更好地实现自己的使用计数器。这样你就可以完全控制这个,而不是使用shared_ptr的那个,正如你所说的那样,不建议这样做。您还可以预先设置自己的计数器,以允许您知道需要对数据执行操作的线程数量,而不是依赖它们在开始时初始化以获取其结构副本。

3

如果你想知道该使用次数是否为1,使用unique()成员函数。

2

我会说你的应用程序应该有一定的消除从应用程序的其他部分为富所有引用的方法,并且该方法应该用来代替检查use_count()。另外,如果use_count()大于1,你的程序会做什么?您不应该依赖shared_ptr的功能来消除所有引用,您的应用程序体系结构应该能够消除引用。作为从矢量中删除它之前的最终检查,您可以通过assert(unique())来验证它是否真的被释放。

2

我认为您可以使用shared_ptr的自定义删除功能在最后一个副本发布时调用特定功能。那样,你根本就没有使用use_count

您需要在您的vector中保存除shared_ptr副本以外的内容,以便shared_ptr仅跟踪未完成的处理。

Boost在shared_ptr文档中有several examples of custom deleters

相关问题