The boost::thread_specific_ptr is a smart pointer that knows about multithreading and ensures that each of its instances is specifically allocated for the current thread.

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;

   class Count
      int step_;
      static boost::mutex mio_;
      static boost::thread_specific_ptr<int> ptrSpec_;
      static boost::scoped_ptr<int> ptrUnique_;

      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));
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