To appreciate the difference with a normal smart pointer we can have a look at this example:
#include <iostream> #include "boost/thread/thread.hpp" #include "boost/thread/mutex.hpp" #include "boost/thread/tss.hpp" #include "boost/scoped_ptr.hpp" using namespace std; namespace { class Count { private: int step_; static boost::mutex mio_; static boost::thread_specific_ptr<int> ptrSpec_; static boost::scoped_ptr<int> ptrUnique_; public: Count(int step) : step_(step) {} void operator()() { if(ptrSpec_.get() == nullptr) // 2. { ptrSpec_.reset(new int(0)); // 3. } for(int i = 0; i < 10; ++i) { boost::mutex::scoped_lock lock(mio_); *ptrSpec_ += step_; *ptrUnique_ += step_; cout << boost::this_thread::get_id() << ": " << *ptrSpec_ << ' ' << *ptrUnique_ << endl; } } }; boost::mutex Count::mio_; boost::thread_specific_ptr<int> Count::ptrSpec_; boost::scoped_ptr<int> Count::ptrUnique_(new int(0)); // 1. } void dd05() { boost::thread t1(Count(1)); boost::thread t2(Count(-1)); t1.join(); t2.join(); }Notice the differences between the scoped_ptr and the thread_specific_ptr.
The scoped ptr is initialized when the variable is defined (1.) and, being a "normal" static data member, is available just in one instance for all the objects of the class Count.
On the other side we have the thread specific ptr. Even though is a static object we have a specific copy of it for each Count object. Given that, we can't expect to have it initialized as any other "normal" static data. We have instead to go through a special routine. Before its first usage we should check (2.) if the pointer is not set, if that is the case, we reset() the value of the smart pointer.
No comments:
Post a Comment