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. 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. 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开发者_JAVA百科 be going out of scope.
Am I misunderstanding something about boost::shared_ptr and 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. This last step is atomic: you either get a strong reference back, or you get a bad_weak_ptr
exception thrown. (Alternatively, call lock()
on the weak_ptr
, and either get a strong reference or null.)
Example (with lock()
; easy enough to adapt to the other style):
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. 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.
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. 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.
Yes, ish. In terms of accessing the pointers, Boost should have made everything safe; 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. (If you're checking appropriately, you should then have an appropro fail case).
But you can't end up with an invalid shared_ptr
精彩评论