I have a configuration of my application stored in a singleton class, like this (simplified):
class Conf
{
Conf();
Conf(const Conf&);
Conf& operator=(const Conf&);
~Conf();
public:
static Conf& instance()
{
static Conf singleton;
return singleton;
};
static void setProperty(const std::string& name,
const std::string& value);
static std::string getProperty(const std::string& name);
private:
QMutex _mutex;
std::map<std::string, std::string> _properties;
};
Because the configuration class can be accessed from many threads, I use mutex for synchronization:
void Conf::setProperty(const std::string& name,
const std::string& value)
{
QMutexLocker(&Conf::instance()._mutex);
Conf::instance()._properties[name]=value;
}
std::string Conf::getProperty(const std::string& name)
{
QMutexLocker(&Conf::instance()._mutex);
return Conf::instance()._properties[name];
}
Does the Conf::instance() method also need a lock?
I have found similar question: does a getter function need a mutex?,
but in my case there is no setter method (lets assume that the instance of the singleton is created before the threads start).
If you're using c++11 or better the creation of the static singleton is guaranteed to be thread safe.
If you're still using c++03 then you need to provide your own mechanism.
by request:
section 6.7 of the c++11 standard:
such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
footnote:
The implementation must not introduce any deadlock around execution of the initializer.
in C++11 instance() does not need mutex, in C++98 it does as two threads might enter it at once an start constructing object. C++11 ensures single initialization of static 'local' variables.
Used this way no, instance() does not need a mutex.
However I would enforce this by moving instance in the private section allowing client code to use just setProperty/getProperty.
Related
I am trying to design a class that works as a data holder (contains lot of members, getters and setters). This class shall be used at multiple other threads in the program and can be used for data exchange, i.e. one component updates the object and others can read out the changed values when needed.
Even if write of a member (by calling setter) can happen only at once place, however getter can be called at multiple places.
Below is the class code.
#include <mutex>
class DataType{};
class DataStore
{
private:
mutable std::mutex _mtx;
DataType _member;
// different other member!
public:
DataStore(): _member(){}
~DataStore(){}
// setters can be called from many places!
void setMember(const DataType& val)
{
std::lock_guard<std::mutex> lock(_mtx);
_member = val;
}
// getters can be called from many places!
const DataType& getMember() const
{
std::lock_guard<std::mutex> lock(_mtx);
return member;
}
};
Questions:
What is best way to create and share instance of this class, singleton or const DataStore& or shared_ptr<DataStore>?
Do we need to make it thread-safe even if calling setMember happens only at once place? What are the possibilities to make it thread-safe? Will the existing code work?
Some of the setters can be called very frequently, do I need to make the member as reference, DataType& _member;?
What is best way to create and share instance of this class, singleton or const DataStore& or shared_ptr<DataStore>?
Access to the class object is always read operation when you choose singleton or shard_ptr.(I cannot understand what const DataStore& means.)
Do we need to make it thread-safe even if calling setMember happens only at once place? What are the possibilities to make it thread-safe? Will the existing code work?
getMember returns const lvalue reference. So that your code doesn't lock anything. copy object or lock data access outside of this class.
You need to ensure that read operation and write operation doesn't occur at same time.
Some of the setters can be called very frequently, do I need to make the member as reference, DataType& _member;?
As already pointed out, you should use std::shared_mutex outside of the class to avoid object copy. this means that you can simply remove the DataStore class because they are no longer needed.
The following code is an implementation of an alternative singleTon class that uses std::call_once in C++11. Basically, the variable static_instance is declared statically along with static_flag, and once calling getInstance function which is also static function i create the first and only instance of mySingle using call_once.
I'd be happy to hear for any comments regarding code correctness in terms of thread safety, and whether its behavior differ from the standard c++ implementation of defining static variable inside getinstance.
mySingle.h
class mySingle
{
static mySingle *static_instance;
static std::once_flag static_flag;
public:
mySingle();
virtual ~mySingle();
static mySingle* getInstance();
};
mySingle.cpp
#include "mySingle.h"
mySingle * mySingle::static_instance;
std::once_flag mySingle::static_flag;
mySingle::mySingle(){}
mySingle::~mySingle(){}
mySingle* mySingle::getInstance()
{
std::call_once(g_flag, [&]() { static_instance = new mySingle(); });
return (mySingle*) static_instance;
}
From the std c++ call_once, it says
Executes the Callable object f exactly once, even if called concurrently, from several threads.
So one would expect that this is thread safe
I have a class where I want to call a method in a thread.
My methods don't modify the class attributs so I expect them to be const, but they instantiate a thread, so they can't.
What is the best choice between putting the std::thread mutable, remove the const because of the thread, edit : or using detached threads ?
class ValidationSound
{
public:
[... CTOR DTOR ...]
void emitSuccessSoundAsync() const
{
if(m_thread.joinable())
{
m_thread.join();
}
m_thread = std::thread(&ValidationSound::emitSound, this, std::cref(m_bipsParameters.first));
};
void emitFailureSoundAsync() const
{
if(m_thread.joinable())
{
m_thread.join();
}
m_thread = std::thread(&ValidationSound::emitSound, this, std::cref(m_bipsParameters.second));
};
void emitSound(const BipParameters& bipParam) const
{
//BIP BIP THE BUZZER
};
private:
std::pair<BipParameters, BipParameters> m_bipsParameters;
mutable std::thread m_thread;
};
My methods don't modify the class attributs so I expect them to be const, but they instantiate a thread, so they can't.
But your methods do modify class attributes. Your std::thread is a class attribute and once any of your methods are called, that attribute will change (begin running) and continue to change state even after the methods have exited.
What is the best choice between putting the std::thread mutable, remove the const because of the thread, edit : or using detached threads ?
In this case, I'd recommend removing the const from method signatures. Const just confuses the interface and could fool users into thinking it's thread-safe. If the methods were mutex protected and blocked for the duration of the thread execution time, you could make a stronger argument for mutable and const, but given your current implementation I wouldn't.
Edit: Said another way, imagine you've gone ahead and created a single const instance of you ValidationSound class. It would be very easy for a user of this class to call your instance in a way that creates many threads all playing different sounds interleaved at different times. Is that how you'd envision a const instance of this class behaving? It's certainly not how I'd envision it looking purely at the interface.
Now that C++11 has multithreading I was wondering what is the correct way to implement lazy initialized singleton without using mutexes(for perf reasons).
I came up with this, but tbh Im not really good at writing lockfree code, so Im looking for some better solutions.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
# include <atomic>
# include <thread>
# include <string>
# include <iostream>
using namespace std;
class Singleton
{
public:
Singleton()
{
}
static bool isInitialized()
{
return (flag==2);
}
static bool initizalize(const string& name_)
{
if (flag==2)
return false;// already initialized
if (flag==1)
return false;//somebody else is initializing
if (flag==0)
{
int exp=0;
int desr=1;
//bool atomic_compare_exchange_strong(std::atomic<T>* obj, T* exp, T desr)
bool willInitialize=std::atomic_compare_exchange_strong(&flag, &exp, desr);
if (! willInitialize)
{
//some other thread CASed before us
std::cout<<"somebody else CASed at aprox same time"<< endl;
return false;
}
else
{
initialize_impl(name_);
assert(flag==1);
flag=2;
return true;
}
}
}
static void clear()
{
name.clear();
flag=0;
}
private:
static void initialize_impl(const string& name_)
{
name=name_;
}
static atomic<int> flag;
static string name;
};
atomic<int> Singleton::flag=0;
string Singleton::name;
void myThreadFunction()
{
Singleton s;
bool initializedByMe =s.initizalize("1701");
if (initializedByMe)
s.clear();
}
int main()
{
while (true)
{
std::thread t1(myThreadFunction);
std::thread t2(myThreadFunction);
t1.join();
t2.join();
}
return 0;
}
Note that clear() is just for testing, real singleton wouldnt have that function.
C++11 removes the need for manual locking. Concurrent execution shall wait if a static local variable is already being initialized.
§6.7 [stmt.dcl] p4
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
As such, simple have a static function like this:
static Singleton& get() {
static Singleton instance;
return instance;
}
This will work all-right in C++11 (as long as the compiler properly implements that part of the standard, of course).
Of course, the real correct answer is to not use a singleton, period.
Maybe the easiest way to implement a singleton using C++11 is:
WARNING: Although this works according to the C++11 standard (static initialisers are thread-safe), this is not implemented correctly in Microsoft Visual C++ 2012 (static initialisers are NOT thread-safe). If you are targeting VC2012, then you have to use a different approach, as it does not fully implement the C++11 standard.
class Singleton {
public:
static Singleton& Instance() {
// Since it's a static variable, if the class has already been created,
// it won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods.
protected:
Singleton() {
// Constructor code goes here.
}
~Singleton() {
// Destructor code goes here.
}
// And any other protected methods.
}
IMHO, the best way to implement singletons is with a "double-check, single-lock" pattern, which you can implement portably in C++ 11:
Double-Checked Locking Is Fixed In C++11
This pattern is fast in the already-created case, requiring only a single pointer comparison, and safe in the first-use case.
As mentioned in previous answer, C++ 11 guarantees construction-order safety for static local variables Is local static variable initialization thread-safe in C++11? so you are safe using that pattern. However, Visual Studio 2013 does not yet support it :-( See the "magic statics" row on this page, so if you are using VS2013 you still need to do it yourself.
Unfortunately, nothing is ever simple. The sample code referenced for the pattern above cannot be called from CRT initialization, because the static std::mutex has a constructor, and is thus not guaranteed to be initialized before the first call to get the singleton, if said call is a side-effect of CRT initialization. To get around that, you have to use, not a mutex, but a pointer-to-mutex, which is guaranteed to be zero-initialized before CRT initialization starts. Then you would have to use std::atomic::compare_exchange_strong to create and use the mutex.
I am assuming that the C++ 11 thread-safe local-static-initialization semantics work even when called during CRT initialization.
So if you have the C++ 11 thread-safe local-static-initialization semantics available, use them. If not, you have some work to do, even moreso if you want your singleton to be thread-safe during CRT initialization.
template<class T>
class Resource
{
Resource<T>(const Resource<T>&) = delete;
Resource<T>& operator=(const Resource<T>&) = delete;
static unique_ptr<Resource<T>> m_ins;
static once_flag m_once;
Resource<T>() = default;
public :
virtual ~Resource<T>() = default;
static Resource<T>& getInstance() {
std::call_once(m_once, []() {
m_ins.reset(new Resource<T>);
});
return *m_ins.get();
}
};
It is hard to read your approach as you are not using the code as intended... that is, the common pattern for a singleton is calling instance() to get the single instance, then use it (also, if you really want a singleton, no constructor should be public).
At any rate, I don't think that your approach is safe, consider that two threads try to acquire the singleton, the first one that gets to update the flag will be the only one initializing, but the initialize function will exit early on the second one, and that thread might proceed to use the singleton before the first thread got around to complete initialization.
The semantics of your initialize are broken. If you try to describe / document the behavior of the function you will have some fun, and will end up describing the implementation rather than a simple operation. Documenting is usually a simple way to double check a design/algorithm: if you end up describing how rather than what, then you should get back to design. In particular, there is no guarantee that after initialize completes the object has actually been initialized (only if the returned value is true, and sometimes if it is false, but not always).
#pragma once
#include <memory>
#include <mutex>
namespace utils
{
template<typename T>
class Singleton
{
private:
Singleton<T>(const Singleton<T>&) = delete;
Singleton<T>& operator = (const Singleton<T>&) = delete;
Singleton<T>() = default;
static std::unique_ptr<T> m_instance;
static std::once_flag m_once;
public:
virtual ~Singleton<T>() = default;
static T* getInstance()
{
std::call_once(m_once, []() {
m_instance.reset(new T);
});
return m_instance.get();
}
template<typename... Args>
static T* getInstance2nd(Args&& ...args)
{
std::call_once(m_once, [&]() {
m_instance.reset(new T(std::forward<Args>(args)...));
});
return m_instance.get();
}
};
template<typename T> std::unique_ptr<T> Singleton<T>::m_instance;
template<typename T> std::once_flag Singleton<T>::m_once;
}
This version complies to be concurrent free where c++11 standard is not guaranteed to be 100% supported. It offers also a flexible way to instantiate the "owned" instance.
Even if the magic static word is enough in c++11 and greater the developer may have the necessity to get much more control over the instance creation.
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?
GCC provides thread safe initialization of static variables.
So, if you use GCC you do not need to care about proper initialization of static variables
You do need to use locking. However, the boost::mutex scheme you propose is broken since you allocate the mutex on the stack and multiple concurrent callers would each get their own mutex.
Try to use the Meyers Singleton implementation.
class MySingleton {
public:
static MySingleton& getInstance() {
static MySingleton instance;
return instance;
}
private:
MySingleton();
~MySingleton();
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
};
MySingleton::MySingleton()= default;
MySingleton::~MySingleton()= default;
// Usage
int main() {
MySingleton::getInstance();
}
More info...