Link to home
Start Free TrialLog in
Avatar of JHaack
JHaack

asked on

Smart Pointers and Multithreading

I have a SmartPtr class that implements reference counting and garbage collections. First of all, I am weary about it's completeness.  Is there a complete SmartPtr class that acts exactly (or nearly) like a regular pointer available.  Second, since threads each have their own stack, are smart pointers useful for multithreading?  It seems to me that since threads share resources (heap, GDI, etc), the smart pointer would be ideal for multithreading memory management.  Ultimately, I'm looking for a complete smart pointer and a good discussion (or book/article) on the various uses of smart pointers, including their applicability to multithreading.
Avatar of Tommy Hui
Tommy Hui

One good reference I saw is in Scott Meyer's More Effective C++: Item 28 on page 159. Actually, his books are really good (Effective C++).

Avatar of JHaack

ASKER

I'm looking for the application of smart pointers in multithreading.  I agree that "More Effective C++" is a good reference on smart pointers, but it doesn't really provide me with any information that I didn't already know.  As I indicated in the question, I have already implemented a smart pointer.  Beyond that, I'm looking for a commercial-level/standard smart pointer and, most importantly, a discussion on the application of smart pointers in multithreading.
ASKER CERTIFIED SOLUTION
Avatar of anichini
anichini

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
whoops, it screwed up my spacing on the timeline:

Thread 1: fetches ref count (temp= meef.m_nRefCount; // == 2)
Thread 1: increments it (temp++)
(task switch)
Thread 2: fetches ref count (temp = meef.m_nRefCount; // == 2)
Thread 2: increments it (temp++)
Thread 2: stores ref count (meef.m_nRefCount = temp; // == 3)
(task switch)
Thread 1: stores ref count (meef.m_nRefCount = temp; // == 3!!)

 
Avatar of JHaack

ASKER

I'm pretty sure I can synchronize my smart pointer to be thread safe.  However, I am a little unclear about how to share smart pointers between threads.  I've always used handles to create shared pointers.  Isn't there a problem in passing pointers between threads?  Specifically, I want to allocate data on the heap using a smart pointer in the primary thread.  Secondary threads will then use the heap data, incrementing the refcount when they start and decrementing it when they finish - not worrying about whether the heap should be freed.  If you could provide a snippet of code that illustrates the concept, I would greatly appreciate it.  Otherwise, thank you for the excellent help that you've already provided.

P.S.  Do you know of any good articles/books on smart pointers and multithreading?
I haven't run across any articles or books that deal with smart pointers in a multithreaded context.

generally, this is how I would go about the scenario you describe (this isn't garuanteed to be syntactically correct, but it is conceptually correct):

struct ThreadArgs
{
  MeefSmartPointer ptr; // MeefSmartPointer is a smart pointer to
                        // type CMeef
};

void thread1(void *pArg)
{
  ThreadArgs *p = (ThreadArgs *)pArg;
  MeefSmartPointer ptr = p->ptr; // meef ref count == 3
  delete p; // free up arguments // meef ref count == 2
  while(1)
  {
   // do our thing with our reference to the shared data in ptr
  }
  // when we exit, we decrement meef's ref count
}

#define STACK_SIZE (1<<14) // stack size of 16K
void main()
{
  MeefSmartPtr ptr = new CMeef; // increments ref count to 1

  ThreadArgs *p = new ThreadArgs;
  p->ptr = ptr; // ref count = 2 now
  _beginthread(thread1, STACK_SIZE, (void *)p);
  // worker thread deletes arguments
  while(1)
  {
    // do our main thread thing
  }
  // when we exit, we decrement the meef's ref count
}

This allows both threads to acces the data (the CMeef object) and keeps a reference count to it. As long as the ref counting is implemented as I described above, this is thread safe. Note that since we're never really sharing a smart pointer between two threads (i.e. the main thread and thread1 do not access the passed smart pointer itself at the same time, only the CMeef object), you don't need to worry about synchronizing the smart pointer's copy constructors/assignment operators.