简体   繁体   English

在多线程程序中增强weak_ptr以实现资源池

[英]Boost weak_ptr's in a multi-threaded program to implement a resource pool

I'm thinking of using boost::weak_ptr to implement a pool of objects such that they will get reaped when nobody is using one of the objects. 我正在考虑使用boost :: weak_ptr来实现一个对象池,这样当没有人使用其中一个对象时它们就会被收获。 My concern, though, is that it's a multi-threaded environment, and it seems there's a race condition between the last shared_ptr to an object going out of scope and a new shared_ptr being constructed from the weak_ptr. 但我担心的是,它是一个多线程环境,似乎最后一个shared_ptr与一个超出范围的对象和一个从weak_ptr构造的新shared_ptr之间存在竞争条件。 Normally, you'd protect such operations with lock or something; 通常情况下,您可以通过锁定或其他方式保护此类操作; however, the whole point here is that you don't know when the shared_ptr might be going out of scope. 但是,这里的重点是你不知道shared_ptr何时可能超出范围。

Am I misunderstanding something about boost::shared_ptr and boost::weak_ptr? 我是否误解了关于boost :: shared_ptr和boost :: weak_ptr的事情? If not, does anybody have any good suggestions on what to do? 如果没有,是否有人对如何做有任何好的建议?

Thanks. 谢谢。

Andrew 安德鲁

To use a weak_ptr , you normally have to grab a strong reference by constructing a shared_ptr with it. 要使用weak_ptr ,通常需要通过构造shared_ptr来获取强引用。 This last step is atomic: you either get a strong reference back, or you get a bad_weak_ptr exception thrown. 最后一步是原子的:你要么得到一个强引用,要么抛出bad_weak_ptr异常。 (Alternatively, call lock() on the weak_ptr , and either get a strong reference or null.) (或者,在weak_ptr上调用lock() ,并获得强引用或null。)

Example (with lock() ; easy enough to adapt to the other style): 示例(使用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
    }
}

Both boost::weak_ptr and boost::shared_ptr are similar if it comes to thread safety: they are not thread safe if there is a risk that object is going to be destroyed somewhere. 如果涉及线程安全性, boost::weak_ptrboost::shared_ptr都是相似的:如果存在某个对象将被破坏的风险,它们就不是线程安全的。 If your object referenced in boost::shared_ptr or weak_ptr is being referenced permanently somewhere, then use can use shared/weak ptrs without any risk. 如果boost::shared_ptr或weak_ptr中引用的对象在某处被永久引用,那么use可以使用shared/weak ptrs而不会有任何风险。

But if some operation is going to dereference the last living instance of object, then at that time you cannot do some operations on weak_ptr : in particular: you cannot assign weak_ptr to another weak_ptr because it uses shared_ptr internally. 但是如果某些操作要取消引用最后一个生成的对象实例,那么那时你就不能对weak_ptr做一些操作了:特别是:你不能将weak_ptr分配给另一个weak_ptr因为它在内部使用了shared_ptr Also, you cannot use lock because the result is undefined. 此外,您不能使用锁定,因为结果是未定义的。 Also, expired() method is useless to: it may return true, but then next line of your code, your object might be already expired. 此外, expired()方法没用:它可能返回true,但是然后你的代码的下一行,你的对象可能已经过期了。

Yes, ish. 是的,是的。 In terms of accessing the pointers, Boost should have made everything safe; 在访问指针方面,Boost应该让一切安全; that's part of their point. 这是他们观点的一部分。

However, if you're expecting to have a delay between when the last shared_ptr goes out, and when you want to make the next one, you'll get a null pointer. 但是,如果您希望在最后一次shared_ptr退出之间以及想要创建下一个shared_ptr之间有延迟,那么您将获得一个空指针。 (If you're checking appropriately, you should then have an appropro fail case). (如果你正确检查,你应该有一个适当的失败案例)。

But you can't end up with an invalid shared_ptr 但是你不能得到一个无效的shared_ptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM