"Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on most common platforms.
If your program is single-threaded and does not link to any libraries that might have used shared_ptr in its default configuration, you can #define the macro BOOST_SP_DISABLE_THREADS on a project-wide basis to switch to ordinary non-atomic reference count updates.
(Defining BOOST_SP_DISABLE_THREADS in some, but not all, translation units is technically a violation of the One Definition Rule and undefined behavior. Nevertheless, the implementation attempts to do its best to accommodate the request to use non-atomic updates in those translation units. No guarantees, though.)
You can define the macro BOOST_SP_USE_PTHREADS to turn off the lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based code."
For std::thread, wikipedia state that:
"Concurrency guarantees
Multiple threads can safely access shared_ptr and weak_ptr objects that reference the same object simultaneously without the risk of a race condition. This is because all updates to the reference count is guaranteed to be doneatomically.
Note that this only protects the reference count itself, and not the object being referenced by the smart pointer. The referenced object therefore needs to be protected separately to ensure thread safety."
Globally, you should rely on the fact that boost/std::shared_ptr counting is atomic which suggests that it is ok to use weak_ptr in other threads.
In practice, I have some code in heavily multithreaded context which rely on std::shared_ptr and std::weak_ptr (on VS2012) to be thread-safe
and didn't have any problem so far (the code was in place for 8 months).