I'm using boost singletons (from serialization).
For example, there are some classes which inherit boost::serialization::singleton. Each of them has such define near it's definition (in h-file):
#define appManager ApplicationManager::get_const_instance()
class ApplicationManager: public boost::serialization::singleton<ApplicationManager> { ... };
And I have to call some method from that class each update (nearly 17 ms), for example, 200 times. So the code is like:
for (int i=0; i < 200; ++i)
appManager.get_some_var();
I looked with gprof at function call stack and saw that boost::get_const_instance calls each time. Maybe, in release-mode compiler will optimize this?
My idea is to make some global variable like:
ApplicationManager &handle = ApplicationManager::get_const_instance();
And use handle, so it wouldn't call get_const_instnace each time. Is that right?
Instead of using the Singleton anti-pattern, just a global variable and be done with it. It's more honest.
The main benefit of Singleton is when you want lazy initialization, or more fine grained control over initialization order than a global variable would allow you. It doesn't look like either of these things are a concern for you, so just use a global.
Personally, I think designs with global variables or Singletons are almost certainly broken. But to each h(is/er) own.
If you are bent on using a Singleton, the performance concern you raise is interesting, but likely not an issue as the function call overhead is probably less than 100ns. As was pointed out, you should profile. If it really concerns you a whole lot, store a local reference to the Singleton before the loop:
ApplicationManager &myAppManager = appManager;
for (int i=0; i < 200; ++i)
myAppManager.get_some_var();
BTW, using that #define in that way is a serious mistake. Almost all cases where you use the preprocessor for anything other than conditional compilation based on compile-time flags is probably a poor use. Boost does make extensive use of the pre-processor, but mostly to get around C++ limitations. Do not emulate it.
Lastly, that function is probably doing something important. One of the jobs of a get_instance method for Singletons is to avoid having multiple threads initialize the same Singleton at the same time. With global variables this shouldn't be an issue because they should be initialized before you've started any threads.
Is it really a problem? I mean, does your application really suffers for this behaviour?
I would despise such a solution because, in all effects, you are countering one of the benefits of the Singleton pattern, namely to avoid global variables. If you want to use a global variable, then don't use Singleton at all, right?
Yes, that is certainly a possible solution. I'm not entirely sure what boost is doing with its singleton behind the scenes; you can look that up yourself in the code.
The singleton pattern is just like creating a global object and accessing the global object, in most respects. There are some differences:
1) The singleton object instance is not created until it is first accessed, whereas the global object is created at program startup.
2) Because the singleton object is not created until it is first accessed, it is actually created when the program is running. Thus the singleton instance has access to other fully constructed objects in the program when the constructor is actually running.
3) Because you access the singleton through the getInstance() method (boost's get_const_instance method) there is a little bit of overhead for executing that method call.
So if you're not concerned about when the singleton is actually created, and can live with it being created at program startup, you could just go with a global variable and access that. If you really need the singleton created after the program starts up, then you need the singleton. In that case, you can grab and hold onto a reference to the object returned by get_const_instance() and use that reference.
Something that bit me in the past though you should be aware of. You're actually getting a reference to the object that is owned by the singleton. You don't own that object.
1) Do not write code that would cause the destructor to execute (say, using a shared pointer on the returned reference), or write any other code that could cause the object to end up in a bad state.
2) In a multi-threaded app, take care to correctly lock fields in the object if the object may be used by more than one thread.
3) In a multi-threaded app, make sure that all threads that hold onto references to the object terminate before the program is unloaded. I've seen a case where the singleton's code resides in one DLL library; a thread that holds the reference lives in another DLL library. When the program ends, the thread was still active. The DLL holding the singleton's code was unloaded first; the thread that was still alive tried to do something to the singleton's object and caused a crash.
Singletons have their advantages in situations where you want to control the level of access to something at process or application scope beyond what a global variable could achieve in a more elegant way.
However most singleton objects provided in a library will be designed to ensure some level of thread safety and most likely access to the instance is being locked via a mutex or other critical section of some kind which can affect performance.
In the case of a game or 3d application where performance is key you may want to consider making your own lightweight singleton if thread safety is not a concern and gain some performance.
Related
To my understanding, if the Singleton::instance() is called in different thread, there might be some problem if both call refer to the first construction of the actual instance.
So if I move the first Singleton::instance() call to the very beginning of the program where no other threads are even created, will this be thread safe now?
Of course, all its member variable are protected by mutex guard when used.
This might open your eyes to a thread-safe Singleton and how easy it isn't.
http://silviuardelean.ro/2012/06/05/few-singleton-approaches/
As per before, it's not very robust if you're requiring it to be created before any threads are kicked off.
Worth noting though, if you compile with C++11, then doing as Brian said (static storage + static method) guarantees thread safety. With any previous versions you will need a mutex, and will run into the caveats mentioned in the link I shared.
So if I move the first Singleton::instance() call to the very beginning of the program where no other threads are even created, will this be thread safe now?
Yes, but this element is not within the Singleton's design and would likely be more robust if it were.
You can often allocate it at file scope or in function scope with static storage within a static method. Verify that your compiler generates exclusion around it or add your own mutex there.
Yes, performing the initial instantiation when you can guarantee there is just one thread extant clearly protects it from other threads causing race conditions.
It doesn't feel terribly robust, though. At the very least, plaster the area with warning comments.
Maybe then you don't need lazy initialization of singleton instance?
If you actually want it then you can protect singleton instance with mutex when you construct it.
Just remember not to put in the header.
If you put the implementation in the header, it may be generated in every compilation unit that uses it. Which means it won't be single.
Also don't compile it in static libraries. This can also lead to multiple instances if the code is linked and merges into several non-static libraries.
If there is no additional thread created yet and you make that move before those threads creation, I don't see a real scenario where you might have problems by using the singleton you already created in any new created multi-threaded environment.
The main thread-safe problem of singleton pattern into a multi-threaded environment is about how to prevent two or more "singleton" instances creation by different threads. I have described this scenario into "Multi-threaded environment" section here.
The question may be wrong in wording but the idea is simple. The order of initialisation of global objects in different translation units is not guarantied. If an application consists of two translation units - can compiler potentially generate initialisation code that will start two threads to create global objects in those translation units? This question is similar to this or this but I think the answers don't match the questions.
I will rephrase the question - if a program has several global objects - will their constructors always be called from the same thread (considering that user code doesn't start any threads before main)?
To make this question more practical - consider a case when several global objects are scattered over several translation units and each of them increments single global counter in constructor. If there is no guarantee that they are executed in single thread then access to the counter must be synchronised. For me it's definitely overkill.
UPDATE:
It looks like concurrent initialisation of globals is possible - see n2660 paper (second case)
UPDATE:
I've implemented singleton using singleton_registry. The idea is that declaration using SomeSingleton = singleton<SomeClass>; registers SomeClass for further initialisation in singleton_registry and real singleton initialisation (with all inter-dependencies) happens at the beginning of main function (before I've started any other threads) by singleton_registry (which is created on stack). In this case I don't need to use DLCP. It also allows me to prepare application configuration and disseminate it over all singletons uniformly. Another important use case is usage of singletons with TDD. Normally it's a pain to use singletons in unit tests, but with singleton_registry I can recreate application global objects for each test case.
In fact this is just a development of an idea that all singletons must be initialised at the beginning of function main. Normally it means that singleton user has to write custom initialisation function which handles all dependencies and prepare proper initialisation parameters (this is what I want to avoid).
Implementation looks good except the fact that I may have potential race conditions during singletons registration.
Several projects ago, using vxWorks and C++, a team mate used a non-thread safe pattern from the book (are any of those patterns thread safe?):
10% of system starts failed.
Lesson 1: if you don't explicitly control the when of a CTOR of a global object, it can change from build to build. (and we found no way to control it.)
Lesson 2: Controlling the when of CTOR is probably the easiest solution to lesson 1 (should it become a problem).
In my experience, if you gotta have Global objects (and it seems many would discourage it), consider limiting these globals to pointers initialized to 0:
GlobalObject* globalobject = nullptr;
And only the thread assigned to initialize it will do so. The other threads/tasks can spin wait for access.
In my C++ project I have a singleton class. During project execution, sometimes the same singleton class is accessed from two different thread simultaneously. Resulting in two instances of the singleton class is produced, which is a problem.
How to handle such a cases?
Then it's not a singleton :-)
You'll probably need to show us some code but your basic problem will be with the synchronisation areas.
If done right, there is no way that two threads can create two objects of the class. In fact, the class itself should be the place where the singleton nature is being enforced so that erroneous clients cannot corrupt the intent.
The basic structure will be:
lock mutex
if instance doesn't exist:
instance = new object
unlock mutex
Without something like mutex protection (or critical code section or any other manner in which you can guarantee at the language/library level that two threads can't run the code simultaneously), there's a possibility that thread one may be swapped out between the check and the instantiation, leading to two possible instances of your "singleton".
And, as others will no doubt suggest, singletons may well be a bad idea. I'm not quite in the camp where every use is wrong, the usual problem is that people treat them as "god" objects. They can have their uses but there's often a better way, though I won't presume to tell you you need to change that, since I don't know your use case.
If you get two different instances in different threads you are doing something wrong. Threads, unlike processes, share their memory. So memory allocated in one thread (e.g. for an object instance) is also usable in the other.
If your singleton getting two copies its not guarded with mutex. lock a mutex when getting/accessing/setting the internal object.
I believe You are done something like this if(!_instance)_instance = new Singleton() there lies a critical section. which you need to safe guard with a mutex.
Do not use a singleton, It is a well known Anti-Pattern.
A good read:
Singletons: Solving problems you didn’t know you never had since 1995
If you still want to persist and go ahead with it for reasons known only to you, What you need is a thread safe singleton implementation, something like this:
YourClass* YourClass::getInstance()
{
MutexLocker locker(YourClass::m_mutex);
if(!m_instanceFlag)
{
m_instance = new YourClass();
m_instanceFlag = true;
}
return m_instance;
}
Where MutexLocker is a wrapper class for an normally used Mutex, which locks the mutex when creating its instance and unlocks the mutex the function ends.
I have several places in my code where a function static object is created once, and then used (copied) any time that function is called. One of these functions can be called from any thread. The function doesn't access any shared state other than this static object.
When thread 1 calls the function for the first time, the object is created and initialized. However, (by a stroke of luck) I have a repeatable case where the program switches to thread 2 and calls the same function before initialization is finished. The object is assigned, and used, with bad data!
I'm not sure how to handle this. I'm using critical sections in the initialization code, but that's not even the problem. This object is being used before being initialized in the first place.
I tried making this thread local using __declspec(thread), but that doesn't work for objects, apparently.
I could just surround the whole thing with a critical section, and maybe that's the best solution, but I'm concerned about problems like this cropping up in other parts of the code- it'd be nice to have a general solution.
If you are on Windows you could use the InitOnceExecuteOnce API. More details can be found in this Raymond Chen post. Also look at the more generic std::call_once
Couldn't you use a semaphore on the object, setting the semaphore to be already set to 1 when the object is created, and then decrementing it to zero when the object is initialized (and ready for use).
Just need to keep an eye out for resource starvation though.
A few days ago my friend told me about the situation, they had in their project.
Someone decided, that it would be good to destroy the object of NotVerySafeClass in parallel thread (like asynchronously). It was implemented some time ago.
Now they get crashes, because some method is called in main thread, while object is destroyed.
Some workaround was created to handle the situation.
Ofcourse, this is just an example of not very good solution, but still the question:
Is there some way to prevent the situation internally in NotVerySafeClass (deny running the methods, if destructor was called already, and force the destructor to wait, until any running method is over (let's assume there is only one method))?
No, no and no. This is a fundamental design issue, and it shows a common misconception in thinking about multithreaded situations and race conditions in general.
There is one thing that can happen equally likely, and this is really showing that you need an ownership concept: The function calling thread could call the function just right after the object has been destroyed, so there is no object anymore and try to call a function on it is UB, and since the object does not exist anymore, it also has no chance to prevent any interaction between the dtor and a member function.
What you need is a sound ownership policy. Why is the code destroying the object when it is still needed?
Without more details about the code, a std::shared_ptr would probably solve this issue. Depending on your specific situation, you may be able to solve it with a more lightweight policy.
Sounds like a horrible design. Can't you use smart pointer to make sure the object is destroyed only when no-one holds any references to it?
If not, I'd use some external synchronization mechanism. Synchronizing the destructor with a method is really awkward.
There is no methods that can be used to prevent this scenario.
In multithread programming, you need to make sure that an object will not be deleted if there are some others thread still accessing it.
If you are dealing with such code, it needs fundamental fix
(Not to promote bad design) but to answer your two questions:
... deny running the methods, if destructor was called already
You can do this with the solution proposed by #snemarch and #Simon (a lock). To handle the situation where one thread is inside the destructor, while another one is waiting for the lock at the beginning of your method, you need to keep track of the state of the object in a thread-safe way in memory shared between threads. E.g. a static atomic int that is set to 0 by the destructor before releasing the lock. The method checks for the int once it acquires the lock and bails if its 0.
... force the destructor to wait, until any running method is over
The solution proposed by #snemarch and #Simon (a lock) will handle this.
No. Just need to design the program propertly so that it is thread safe.
Why not make use of a mutex / semaphore ? At the beginning of any method the mutex is locked, and the destructor wait until the mutex is unlocked. It's a fix, not a solution. Maybe you should change the design of a part of your application.
Simple answer: no.
Somewhat longer answer: you could guard each and every member function and the destructor in your class with a mutex... welcome to deadlock opportunities and performance nightmares.
Gather a mob and beat some design sense into the 'someone' who thought parallel destruction was a good idea :)