41

I have a class that I can have many instances of. Inside it creates and initializes some members from a 3rd party library (that use some global variables) and is not thread-safe.

I thought about using static boost::mutex, that would be locked in my class constructor and destructor. Thus creating and destroying instances among my threads would be safe for the 3rd party members.



class MyClass

{
  static boost::mutex mx;

  // 3rd party library members
public:
  MyClass();
  ~MyClass();
};

MyClass::MyClass()
{
  boost::mutex::scoped_lock scoped_lock(mx);
  // create and init 3rd party library stuff
}

MyClass::~MyClass()
{
  boost::mutex::scoped_lock scoped_lock(mx);
  // destroy 3rd party library stuff
}


I cannot link because I receive error:

undefined reference to `MyClass::mx`
  1. Do I need some special initialization of such static member?

  2. Is there anything wrong about using static mutex?


Edit: Linking problem is fixed with correct definition in cpp

boost::mutex MyClass::mx;
Dmitry Yudakov
  • 15,364
  • 4
  • 49
  • 53
  • 2
    If you use a static mutex, you will serialize the use of *all* the instances of your class, completely negating any benefit you may gain through multithreading. Are you sure you want this? – John Dibling Mar 17 '10 at 14:56
  • @John Dibling Yes, only creating and destroying the objects will be protected - it will not happen too often. The rest of the time the instances will be used without locking the mutex and it should be quite efficient. – Dmitry Yudakov Mar 17 '10 at 15:03
  • 1
    @Dmity: Which leads me to my next question: are you sure it will be safe to use the instances without locking? – John Dibling Mar 17 '10 at 16:05
  • @John Dibling The 3rd party library provide some locking mechanism that's supposed to guaranty thread-safe work, but they need existing objects - my tests showed that it's working. It seems though that concurrent creating of these objects in not very safe. – Dmitry Yudakov Mar 17 '10 at 16:17
  • Remember that a `static` data member of a `class` will be shared among all instances of the class *AND* instances of derived classes. You may want to reconsider the `static` qualifier. – Thomas Matthews Mar 17 '10 at 16:59
  • @Thomas I'm aware of it, that's exactly what I want and I'm not planning to derive this class. Using this static mutex seems like the easiest solution comparing to Factory for example. – Dmitry Yudakov Mar 17 '10 at 17:29

2 Answers2

62

You have declared, but not defined your class static mutex. Just add the line

boost::mutex MyClass::mx;

to the cpp file with the implementation of MyClass.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
Stephen C. Steel
  • 4,380
  • 1
  • 20
  • 21
3

The question was made a long time ago but merely to update the post, now you can use inline variable:

inline static std::mutex mx;

that does the ODR rule, solving those linkage problems.

UPDATE

Yep, as @isudfv pointed out, it's available since C++17.

Dean Seo
  • 5,486
  • 3
  • 30
  • 49