Reply to comment

Thread Safety Locking Strategies

I'm going to cover a thread safety strategy I have been thinking about lately. Let's look at an example for a typical "lock the variables as you use them" approach:

class Stuff
{
  public:
    void doSomething()
    {
      setString();
      checkString();
    }
 
  private:
    string myString;
    boost::mutex myMutex;
 
    void setString()
    {
      boost::mutex::scoped_lock l(myMutex); // Lock before touching local vars
      myString = "hello world";
    }
 
    void checkString()
    {
      boost::mutex::scoped_lock l(myMutex); // Lock before touching local vars
      assert(myString == "hello world");
    }
};

I am proposing the following changes to the typical approach:

  1. Prefer to not use member data in private methods. This rule could be enforced by making all private methods static, if desired.
  2. Place general locks on all public facing methods. This assures that only one thread can be accessing your class at a time

Pros to this method:

  • Not using object level data in a private method enhances composability of the private methods and makes them more able to be used with the standard algorithms.
  • Coarser grained locks are easier to debug.
  • In sufficiently large classes object level data can start to look like global variables, this avoids that problem
  • Using future methods, such as transactional objects, will become a more natural change, one can just "check out" the object at the beginning of the public method

Cons:

  • Coarser grained locks are less parallelizable, we may be wasting CPU time with this method

This is the result of those changes. Compared it to the above example, it's a bit more concise. I think I would like to call this "Level 1 Thread Safety." By building your classes that need to be thread safe like this you can get thread safety quickly and cheaply, and have the capability to move into more efficient methods in the future if you need to.

class Stuff
{
  public:
    void doSomething()
    {
      boost::mutex::scoped_lock l(myMutex);
      setString(myString);
      checkString(myString);
    }
 
  private:
    string myString;
    boost::mutex myMutex;
 
    void setString(string &s)
    {
      s = "hello world";
    }
 
    void checkString(const string &s)
    {
      assert(s == "hello world");
    }
};

Reply

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • Lines and paragraphs break automatically.
  • You may post PHP code. You should include <?php ?> tags.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.
  • Images can be added to this post.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.