4

我正在考虑使用 boost::weak_ptr 来实现一个对象池,这样当没有人使用其中一个对象时它们就会被收割。不过,我担心的是它是一个多线程环境,并且似乎在最后一个 shared_ptr 到超出范围的对象与从weak_ptr 构造的新 shared_ptr 之间存在竞争条件。通常,您会使用锁定或其他东西来保护此类操作;但是,这里的重点是您不知道 shared_ptr 何时可能超出范围。

我对 boost::shared_ptr 和 boost::weak_ptr 有误解吗?如果没有,是否有人对该怎么做有什么好的建议?

谢谢。

安德鲁

4

3 回答 3

11

要使用 a weak_ptr,您通常必须通过构造 a 来获取强引用shared_ptr。最后一步是原子性的:要么得到强引用,要么bad_weak_ptr抛出异常。(或者,调用lock(),weak_ptr并获得强引用或 null。)

示例(使用lock(); 很容易适应其他风格):

void do_something(weak_ptr<foo> weak) {
    // Grab strong reference
    shared_ptr<foo> strong(weak.lock());
    if (strong) {
        // We now have a strong reference to use
    } else {
        // No strong references left; object already freed
    }
}
于 2010-01-29T07:04:40.950 回答
3

两者在线程安全boost::weak_ptr方面boost::shared_ptr是相似的:如果存在对象将在某处被销毁的风险,它们就不是线程安全的。如果您在boost::shared_ptr或weak_ptr 中引用的对象在某处被永久引用,那么使用可以shared/weak毫无风险地使用ptrs。

但是,如果某些操作要取消引用对象的最后一个活实例,那么那时您不能对weak_ptr: 执行某些操作,特别是:您不能分配weak_ptr给另一个weak_ptr,因为它在shared_ptr内部使用。此外,您不能使用锁定,因为结果未定义。此外,expired()方法无用:它可能会返回 true,但是在您的代码的下一行,您的对象可能已经过期。

于 2012-01-18T13:10:18.437 回答
0

是的,伊什。在访问指针方面,Boost 应该确保一切安全;这是他们的观点的一部分。

但是,如果您希望在最后一个 shared_ptr 熄灭和您想要制作下一个之间有延迟,您将获得一个空指针。(如果您检查得当,那么您应该有一个 appropro 失败案例)。

但是你不能得到一个无效的 shared_ptr

于 2010-01-29T07:10:15.793 回答