Boost logo

Boost :

From: John Maddock (john_at_[hidden])
Date: 2006-03-27 04:52:01


> By default shared_ptr is now compiled to be non thread safe (I could
> be
> wrong here, I am confused by all of the conflicting comments I have
> seen).

No the pointer itself is always thread safe if it's possible to make it so,
the thing it points to is not thread safe unless you choose to make it so.

> It is also compiled this why in my local version. It seems
> that
> the delete/cleanup is the only problem since the reference count
> seems to
> be wrapped into a atomic function. Since I really cannot control the
> deletion/going out of scope of the pointers, is shared_ptr any use in
> a threaded application? I was looking to see if writing my own
> "deleter"
> would solve this program (one that I could make it thread safe), but
> it
> looks like this gets called after the part where it is determined if
> the deleter should be called.

I don't understand what you are asking here: of course the deleter is thread
safe: if the reference count is handled by atomic operations (ie thread
safe), then when the count reaches zero *there is only one thread left
observing the pointer* so deletion is necessarily thread safe. Note that
I'm assuming there is no thread trying to copy the shared_ptr at the same
time as it's destructor is being called by second thread: that would be a
design error if it occurred!

What that means in practice is you can:

1) Create a shared_ptr to a const object, and safely pass that object around
between threads, and access both the pointer and the immutable object to
which it points from whatever threads you want. *As long as there is no
thread that has a mutable pointer to the object*.

2) Create a class that uses the pimpl idiom and copy-on-write in an entirely
thread safe manner: all mutating operations will be preceded by a copy
operation leading to a thread-local copy of the original object. While
non-mutating operations may safely use shared access to the same underlying
object.

While you can *not* do:

1) Have multiple threads accessing the object *pointed to* a shared_ptr if
any of those threads mutate the object. In this case you would need a
separate mutex to govern all accesses to the object (*both read and write*),
this is *in addition to* the thread safety guarantees offered by shared_ptr.

And finally: while it is technically possible to create a smart pointer that
"monitors" all access to the object to which it points - for example making
all accesses thread safe - such smart pointers have a more restricted
interface than shared_ptr, and are typically needlessly inefficient compared
to a separate mutex (think multiple accesses chained together).

Whew. If that's not clear enough don't write multithreaded code :-)
Honestly shared_ptr analysis is easy compared to most concurrent problems
(so here's hoping I haven't made any stupid mistakes in the above!)

John.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk