I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
Related
I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
I need to make own simple thread-safe shared pointer class for embedded devices.
I made counting master pointer and handle as described in Jeff Alger's book (C++ for real programmers). This is my sources:
template <class T>
class counting_ptr {
public:
counting_ptr() : m_pointee(new T), m_counter(0) {}
counting_ptr(const counting_ptr<T>& sptr) :m_pointee(new T(*(sptr.m_pointee))), m_counter(0) {}
~counting_ptr() {delete m_pointee;}
counting_ptr<T>& operator=(const counting_ptr<T>& sptr)
{
if (this == &sptr) return *this;
delete m_pointee;
m_pointee = new T(*(sptr.m_pointee));
return *this;
}
void grab() {m_counter++;}
void release()
{
if (m_counter > 0) m_counter--;
if (m_counter <= 0)
delete this;
}
T* operator->() const {return m_pointee;}
private:
T* m_pointee;
int m_counter;
};
template <class T>
class shared_ptr {
private:
counting_ptr<T>* m_pointee;
public:
shared_ptr() : m_pointee(new counting_ptr<T>()) { m_pointee->grab(); }
shared_ptr(counting_ptr<T>* a_pointee) : m_pointee(a_ptr) { m_pointee->grab(); }
shared_ptr(const shared_ptr<T>& a_src) : m_pointee(a_src.m_pointee) {m_pointee->grab(); }
~shared_ptr() { m_pointee->release(); }
shared_ptr<T>& operator=(const shared_ptr<T>& a_src)
{
if (this == &a_src) return *this;
if (m_pointee == a_src.m_pointee) return *this;
m_pointee->release();
m_pointee = a_src.m_pointee;
m_pointee->grab();
return *this;
}
counting_ptr<T>* operator->() const {return m_pointee;}
};
This works fine if it used in one thread. Suppose I have two threads:
//thread 1
shared_ptr<T> p = some_global_shared_ptr;
//thread 2
some_global_shared_ptr = another_shared_ptr;
This case I can get undefined behaviour if one of threads will be interrupted between memory allocating/deallocating and counter changing. Of course I can enclose shared_ptr::release() into critical section so deletion of the pointer can be made safety. But what can I do with copy constructor? It is possible that constructor will be interrupted during m_pointee construction by another thread which will delete this m_pointee.
The only way I see to make shared_ptr assignement thread-safe is to enclose the assignment (or creation) into critical section. But this must be done in "user code". In other words user of shared_ptr class must take care about safety.
Is it possible to change this realization somehow to make the shared_ptr class thread safe?
=== EDIT ===
After some investigations (thanks to Jonathan) I realized that my shared_ptr has three unsafe places:
Unatomic counter changing
Unatomic assignment operator (source object can be deleted during copying)
shared_ptr copy constructor (very similar to previous case)
First two cases could be easily fixed by adding crtical sections. But I can't realize how to add critical section into copy constructor? Copy of a_src.m_pointee created before any other code in the constructor executed and can be deleted before calling grab. As Jonathan said in his comment it is very difficult to fix this problem.
I made such test:
typedef shared_ptr<....> Ptr;
Ptr p1, p2;
//thread 1
while (true)
{
Ptr p;
p2 = p;
}
//thread 2
while (!stop)
{
p1 = p2;
Ptr P(p2);
}
Of course, it crashed. But I have tried to use std::shared_ptr in VS 2013 C++. And it works!
So it is possible to make thread-safe copy constructor for shared_ptr. But stl sources too difficult for me and I don't understand how they did the trick. Please anyone explain me how it works in STL?
=== EDIT 2 ===
I am sorry, but the test for std::shared_ptr was made wrong. It doesn't pass too exactly as boost::shared_ptr does. Sometimes copy constructor fails to make a copy because source was deleted during copying. In this case empty pointer will be created.
This is hard to get right, I would seriously consider whether you actually need to support concurrent reads and writes of a single object (boost::shared_ptr and std::shared_ptr do not support that unless all accesses are done through the atomic_xxx() functions that are overloaded for shared_ptr and which typically acquire a lock).
For a start you would need to change shared_ptr<T>::m_pointee to atomic<counting_ptr<T>*> so that you can store a new value in it atomically. counting_ptr<T>::m_counter would need to be atomic<int> so the ref-count updates can be done atomically.
Your assignment operator is a big problem, you would need to at least re-order the operations so you increase the ref-count first, and avoid time of check to time of use bugs, something like this (not even compiled, let alone tested):
shared_ptr<T>& operator=(const shared_ptr<T>& a_src)
{
counter_ptr<T>* new_ptr = a_src.m_pointee.load();
new_ptr->grab();
counter_ptr<T>* old_ptr = m_pointee.exchange(new_ptr);
old_ptr->release();
return *this;
}
This form is safe against self-assignment (it just increases the ref-count then decreases it again if the two objects share the same pointee). It's still not safe against a_src changing while you try to copy it. Consider the case where a_src.m_pointee->m_counter == 1 initially. The current thread could call load() to get the other object's pointer, then a second thread could call release() on that pointer, which would delete it, making the grab() call undefined behaviour because it accesses an object that has been destroyed and memory that has been deallocated. Fixing that requires a pretty major redesign and maybe atomic operations that can operate on two words at once.
Getting this right is possible but is hard and you should really reconsider whether it's necessary, or if the code using it can just avoid modifying objects while other threads are reading them, except while the user has locked a mutex or other form of manual synchronisation.
After some investigations I can conclude that it is impossible to make thread-safe shared_ptr class where thread-safety understood as follow:
//thread 1
shared_ptr<T> p = some_global_shared_ptr;
//thread 2
some_global_shared_ptr = another_shared_ptr;
This example doesn't guarantees that p in first thread will point to old or new value of some_global_shared_ptr. In general this example leads to undefined behavior. The only way to make the example safety is to wrap both operators into critical sections or mutial exclusions.
The main problem caused by copy constructor of shared_ptr class. Other problems could be solved using critical sections inside shared_ptr methods.
Just inherit your class from CmyLock and you can make everything thread safe.
I use this class already many years in all my code, usually combined with class CmyThread, which creates a thread that has a very safe mutex. Maybe my answer is a little late, but above answers are not good practice.
/** Constructor */
CmyLock::CmyLock()
{
(void) pthread_mutexattr_init( &m_attr);
pthread_mutexattr_settype( &m_attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init( &m_mutex, &m_attr);
}
/** Lock the thread for other threads. */
void CmyLock::lock()
{
pthread_mutex_lock( &m_mutex);
}
/** Unlock the thread for other threads. */
void CmyLock::unlock()
{
pthread_mutex_unlock( &m_mutex);
}
Here also the thread class. Try Please copy CmyLock and CmyThread classes to your project and tell when it's working! Although it's made for Linux, also Windows and Mac should be able to run this.
For the include file:
// #brief Class to create a single thread.
class CmyThread : public CmyLock
{
friend void *mythread_interrupt(void *ptr);
public:
CmyThread();
virtual ~CmyThread();
virtual void startWorking() {}
virtual void stopWorking() {}
virtual void work();
virtual void start();
virtual void stop();
bool isStopping() { return m_stopThread; }
bool isRunning() { return m_running && !m_stopThread; }
private:
virtual void run();
private:
bool m_running; ///< Thread is now running.
pthread_t m_thread; ///< Pointer to thread.
bool m_stopThread; ///< Indicate to stop thread.
};
The C++ file:
/** #brief Interrupt handler.
* #param ptr [in] SELF pointer for the instance.
*/
void *mythread_interrupt(void *ptr)
{
CmyThread *irq =
static_cast<CmyThread*> (ptr);
if (irq != NULL)
{
irq->run();
}
return NULL;
}
/** Constructor new thread. */
CmyThread::CmyThread()
: m_running( false)
, m_thread( 0)
, m_stopThread( false)
{
}
/** Start thread. */
void CmyThread::start()
{
m_running =true;
m_stopThread =false;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int stack_size =8192*1024;
pthread_attr_setstacksize(&attr, stack_size);
pthread_create(&m_thread, &attr, mythread_interrupt, (void*) this);
}
/** Thread function running. */
void CmyThread::run()
{
startWorking();
while (m_running && m_stopThread==false)
{
work();
}
m_running =false;
stopWorking();
pthread_exit(0);
}
/** Function to override for a thread. */
virtual void CmyThread::work()
{
delay(5000);
}
For example, here a simplistic example to store and retrieve 1000 data:
class a : public CmyLock
{
set_safe(int *data)
{
lock();
fileContent =std::make_shared<string>(data);
unlock();
}
get_safe(char *data)
{
lock();
strcpy( data, fileContent->c_str());
unlock();
}
std::shared_ptr<string> fileContent;
};
I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
I have been reading about thread safe singletons and the implementation I find everywhere has a getInstance() method something like this:
Singleton* getInstance()
{
if ( !initialized )
{
lock();
if ( !initialized )
{
instance = new Singleton();
initialized = true;
}
unlock();
}
return instance;
}
Is this actually thread safe?
Have I missed something or is there a small chance this function will return an uninitialized instance because 'initialized' may be reordered and set before instance?
This article is on a slightly different topic but the top answer describes why I think the above code is not thread safe:
Why is volatile not considered useful in multithreaded C or C++ programming?
Not a good idea. Look for double check locking. For instance:
http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405726
http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405772
It is indeed not thread safe, because after the pointer gets returned you still work with it, although the mutex is unlocked again.
What you can do is making the child class which inherits from singleton, thread safe. Then you're good to go.
Below is the code for a thread-safe singleton, using Double Check and temporary variable. A temporary variable is used to construct the object completely first and then assign it to pInstance.
Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
Singleton* temp = new Singleton; // initialize to temp
pInstance = temp; // assign temp to pInstance
}
}
return pInstance;
}
I have a doubt related to Singleton and multithread programming in C++
Following you can see an example code of a Singleton class with a variable named shared.
I create 1000 threads that modify (+1) that variable of my Singleton global instance. The final value of shared is 1000 but I would expect this value to be under 1000 since I am not protecting this variable for concurrency.
Is the code really thread safe because the class is Singleton or it just happened to be lucky and the value is 1000 but it can perfectly be less than 1000?
#include <iostream>
using namespace std;
class Singleton {
private:
Singleton() {shared = 0;};
static Singleton * _instance;
int shared;
public:
static Singleton* Instance();
void increaseShared () { shared++; };
int getSharedValue () { return shared; };
};
// Global static pointer used to ensure a single instance of the class.
Singleton* Singleton::_instance = NULL;
Singleton * Singleton::Instance() {
if (!_instance) {
_instance = new Singleton;
}
return _instance;
}
void * myThreadCode (void * param) {
Singleton * theInstance;
theInstance = Singleton::Instance();
theInstance->increaseShared();
return NULL;
}
int main(int argc, const char * argv[]) {
pthread_t threads[1000];
Singleton * theInstance = Singleton::Instance();
for (int i=0; i<1000; i++) {
pthread_create(&threads[i], NULL, &myThreadCode, NULL);
}
cout << "The shared value is: " << theInstance->getSharedValue() << endl;
return 0;
}
Is the code really thread safe because the class is Singleton or it just happened to be lucky and the value is 1000 but it can perfectly be less than 1000?
You got lucky...
In reality, the most likely issue with what you're observing has to-do with the fact that the time it takes to increment the value of your singleton on your specific machine is less than the time it takes the operating system to allocate the resources to launch an individual pthread. Thus you never ended up with a scenario where two threads contend for the unprotected resources of the singleton.
A much better test would have been to launch all of your pthreads first, have them block on a barrier or condition variable, and then perform the increment on the singleton once the barrier's condition of all the threads being "active" is met ... at that point you would have been much more likely to have seen the sorts of data-races that occur with non-atomic operations like an increment operation.
If you implement your Singleton like this, the singleton creation will be thread safe:
Singleton & Singleton::Instance() {
static Singleton instance;
return instance;
}
Since the instance can never be null, and no memory to manager, a reference is returned instead of a pointer.
The increment operation can be made atomic by using platform specific operations (g++ provides built-ins, e.g. __sync_fetch_and_add), or C++11 atomic from STL, or Boost.Atomic, or with mutex guards.
std::atomic<int> shared;
void increaseShared () { ++shared; };