I am currently trying to write a threadsafe singleton (at least in terms of construction and destruction) using boost::mutex. I read that boost mutex can’t be initialized statically(I lost the link where I read it, sorry) so to work around that I tried this, if threadsafety for construction and destruction is:
static T& getInstance()
{
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
boost::mutex mutex;
boost::lock_guard lock(mutex);
#endif
static T instance;
return instance;
}
is that threadsafe, or should I use boost::call_once? Will boost once give me any performance benefit over this approach?
EDIT:
Okay, my first idea was obviously not correct. To clearify the question. Can a boost::mutex safely be initialized statically? Like this:
class Singleton
{
private:
static boost::mutex m_mutex;
public:
static Singleton & getInstance()
{
boost::lock_guard lock(m_mutex);
static T instance;
return instance;
}
};
Is that a working approach or is it in fact not safe to init boost::mutex statically (which is what I read)?
EDIT2:
Ah, that was the link by the way http://uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html
Since each entry to the function will create its own lock, the lock will be completely useless; any number of threads can enter the function, lock different locks, and start messing with the static data at the same time.
You could create the lock at file (or class static) scope; this would ensure it’s created in time, provided that you don’t start threads before
main(). However, this would also serialize entry to the function even after the static data is initialized.Why not just define your static data at file (or class static) scope in the first place?