Designing a thread-safe copyable class

The straightforward way to make a class threadsafe is to add a mutex attribute and lock the mutex in the accessor methods

class cMyClass {
  boost::mutex myMutex;
  cSomeClass A;
public:
  cSomeClass getA() {
    boost::mutex::scoped_lock lock( myMutex );
    return A;
  }
};

The problem is that this makes the class non-copyable. This is important, especially if you want to store objects of the class in a container.

I can make things work by making the mutex a static.

class cMyClass {
  static boost::mutex myMutex;
  cSomeClass A;
public:
  cSomeClass getA() {
    boost::mutex::scoped_lock lock( myMutex );
    return A;
  }
};

However, this means that every instance of the class blocks when any other instance is being accessed, because they all share the same mutex.

Theoretically, a class containing a non-static mutex can be made copyable by hand coding the copy constructor and assignment operator so as to leave out the mutex. However, this is difficult and tedious to do properly, especially for a class with a large number of attributes that frequently change during development.

If a static mutex that blocks access to all instances of the class when one is blocked is not acceptable, then the best and simplest approach is to maintain the mutexes outside the class. It might seem unfortunate to expose the inner workings of a class in this way, but the alternatives are way more complex, hence unreliable, and I frequently find significant optimizations when the mutexes are handled at the level of the code accessing the class.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s