My singleton can be called multiple times





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







27















I have implemented an singleton based on c++ 11.
However the constructor can be called multiple times in some cases.



The class will be compiled to static lib and
used by other so lib (more than one so lib).
And the system is a multi-thread system (run in the Android HAL level)



/// The .h file:



class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


/// the .cpp file



Logger::Logger()
{
ALOGE("OfflineLogger create");
}

Logger::~Logger()
{

}


It should be created once eg:



03-21 01:52:20.785   728  4522 E         : OfflineLogger create


However I can see it has been created more than once



03-21 01:52:20.785   728  4522 E         : OfflineLogger create
03-21 01:52:20.863 728 2274 E : OfflineLogger create
03-21 01:52:20.977 728 2273 E : OfflineLogger create
03-21 01:52:26.370 728 4522 E : OfflineLogger create


Questions:




  1. Anything wrong with my singleton design? Is it a thread-safe issue?


  2. Seems like my singleton works fine in one so scope, but each
    so lib which includes my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "static variable" becomes "local static"?
    Is it possible? If so, how to fix?



Thanks for any input!










share|improve this question




















  • 4





    Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

    – Michael Veksler
    Apr 2 at 6:11








  • 1





    Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

    – Alexander
    Apr 2 at 10:33






  • 1





    @Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

    – Angew
    Apr 2 at 12:38






  • 1





    @Angew Woah, really? They finally have a purpose! That's great to hear

    – Alexander
    Apr 2 at 12:58






  • 4





    Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

    – T.E.D.
    Apr 2 at 13:29




















27















I have implemented an singleton based on c++ 11.
However the constructor can be called multiple times in some cases.



The class will be compiled to static lib and
used by other so lib (more than one so lib).
And the system is a multi-thread system (run in the Android HAL level)



/// The .h file:



class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


/// the .cpp file



Logger::Logger()
{
ALOGE("OfflineLogger create");
}

Logger::~Logger()
{

}


It should be created once eg:



03-21 01:52:20.785   728  4522 E         : OfflineLogger create


However I can see it has been created more than once



03-21 01:52:20.785   728  4522 E         : OfflineLogger create
03-21 01:52:20.863 728 2274 E : OfflineLogger create
03-21 01:52:20.977 728 2273 E : OfflineLogger create
03-21 01:52:26.370 728 4522 E : OfflineLogger create


Questions:




  1. Anything wrong with my singleton design? Is it a thread-safe issue?


  2. Seems like my singleton works fine in one so scope, but each
    so lib which includes my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "static variable" becomes "local static"?
    Is it possible? If so, how to fix?



Thanks for any input!










share|improve this question




















  • 4





    Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

    – Michael Veksler
    Apr 2 at 6:11








  • 1





    Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

    – Alexander
    Apr 2 at 10:33






  • 1





    @Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

    – Angew
    Apr 2 at 12:38






  • 1





    @Angew Woah, really? They finally have a purpose! That's great to hear

    – Alexander
    Apr 2 at 12:58






  • 4





    Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

    – T.E.D.
    Apr 2 at 13:29
















27












27








27


3






I have implemented an singleton based on c++ 11.
However the constructor can be called multiple times in some cases.



The class will be compiled to static lib and
used by other so lib (more than one so lib).
And the system is a multi-thread system (run in the Android HAL level)



/// The .h file:



class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


/// the .cpp file



Logger::Logger()
{
ALOGE("OfflineLogger create");
}

Logger::~Logger()
{

}


It should be created once eg:



03-21 01:52:20.785   728  4522 E         : OfflineLogger create


However I can see it has been created more than once



03-21 01:52:20.785   728  4522 E         : OfflineLogger create
03-21 01:52:20.863 728 2274 E : OfflineLogger create
03-21 01:52:20.977 728 2273 E : OfflineLogger create
03-21 01:52:26.370 728 4522 E : OfflineLogger create


Questions:




  1. Anything wrong with my singleton design? Is it a thread-safe issue?


  2. Seems like my singleton works fine in one so scope, but each
    so lib which includes my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "static variable" becomes "local static"?
    Is it possible? If so, how to fix?



Thanks for any input!










share|improve this question
















I have implemented an singleton based on c++ 11.
However the constructor can be called multiple times in some cases.



The class will be compiled to static lib and
used by other so lib (more than one so lib).
And the system is a multi-thread system (run in the Android HAL level)



/// The .h file:



class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


/// the .cpp file



Logger::Logger()
{
ALOGE("OfflineLogger create");
}

Logger::~Logger()
{

}


It should be created once eg:



03-21 01:52:20.785   728  4522 E         : OfflineLogger create


However I can see it has been created more than once



03-21 01:52:20.785   728  4522 E         : OfflineLogger create
03-21 01:52:20.863 728 2274 E : OfflineLogger create
03-21 01:52:20.977 728 2273 E : OfflineLogger create
03-21 01:52:26.370 728 4522 E : OfflineLogger create


Questions:




  1. Anything wrong with my singleton design? Is it a thread-safe issue?


  2. Seems like my singleton works fine in one so scope, but each
    so lib which includes my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "static variable" becomes "local static"?
    Is it possible? If so, how to fix?



Thanks for any input!







android c++ singleton hal






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 2 at 14:01









Fletch

166




166










asked Apr 2 at 5:02









hismarthismart

172210




172210








  • 4





    Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

    – Michael Veksler
    Apr 2 at 6:11








  • 1





    Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

    – Alexander
    Apr 2 at 10:33






  • 1





    @Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

    – Angew
    Apr 2 at 12:38






  • 1





    @Angew Woah, really? They finally have a purpose! That's great to hear

    – Alexander
    Apr 2 at 12:58






  • 4





    Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

    – T.E.D.
    Apr 2 at 13:29
















  • 4





    Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

    – Michael Veksler
    Apr 2 at 6:11








  • 1





    Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

    – Alexander
    Apr 2 at 10:33






  • 1





    @Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

    – Angew
    Apr 2 at 12:38






  • 1





    @Angew Woah, really? They finally have a purpose! That's great to hear

    – Alexander
    Apr 2 at 12:58






  • 4





    Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

    – T.E.D.
    Apr 2 at 13:29










4




4





Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

– Michael Veksler
Apr 2 at 6:11







Don't forget to delete the copy constructor, otherwise it's easy to create multiple objects. It's a good idea to delete assignment, although it might not harm you too much to assign the object to itself

– Michael Veksler
Apr 2 at 6:11






1




1





Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

– Alexander
Apr 2 at 10:33





Also don't forget that there's no synchronization employed here, so it's still prone to race conditions if it's ever used in a multi-threaded context.

– Alexander
Apr 2 at 10:33




1




1





@Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

– Angew
Apr 2 at 12:38





@Alexander That applies to using the object and not to creating it, though. Since C++11, function-scope static variables are guaranteed to be initialised race-free.

– Angew
Apr 2 at 12:38




1




1





@Angew Woah, really? They finally have a purpose! That's great to hear

– Alexander
Apr 2 at 12:58





@Angew Woah, really? They finally have a purpose! That's great to hear

– Alexander
Apr 2 at 12:58




4




4





Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

– T.E.D.
Apr 2 at 13:29







Here's an idea: Rather than use a singleton, which is both a hard problem in your environment and known to be problematic for testing and maintenance, just design your code to only create one of the object in question.

– T.E.D.
Apr 2 at 13:29














6 Answers
6






active

oldest

votes


















28
















  1. Anything wrong with my singleton design? Is it a thread-safe issue?




No. Initialization of function local static variables is guaranteed to be thread-safe by the standard.





  1. Seems like my singleton works fine in one so scope, but each
    so lib which include my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "staic veriable" become "local static"?
    Is it possible? If so, how to fix




That is the correct conclusion.



Instead of creating a static library that contains the implementation of the singleton, make it a dynamic library.






share|improve this answer
























  • Thanks a lot for the help. Finally I change to use dynamic linking and works fine

    – hismart
    Apr 3 at 9:58











  • @hismart, you are welcome. Glad I was able to help.

    – R Sahu
    Apr 3 at 18:12



















4














Singletons are hard, especially with shared libraries.



Each of your shared libraries has an independent copy of the non-shared library. Without extra care, each will have a copy of the singleton.



In order to have non-trivial singletons, what I have had to do was




  1. Create an extremely low level library to help with singletons -- call it LibSingleton


  2. Create a singleton template that knows the type of the singleton. It uses magic statics to send a request to the LibSingleton with a size, typeid(T).name() key, and type-erased construction and destruction code. LibSingleton returns a reference counting RAII object.


  3. LibSingleton uses a shared mutex to either return a previously constructed object that matches the name/size or constructs it. If it constructs the object, it stores the destruction code.


  4. When the last reference-counted handle to the LibSingleton data goes away, LibSingleton runs the destruction code and cleans up the memory in its unordered map.



This permits really simple singletons to be used nearly anywhere.



template<class T>
class singleton {
public:
static T& Instance() {
static auto smart_ptr = LibSingleton::RequestInstance(
typeid(T).name(),
sizeof(T),
(void* ptr){ return ::new( ptr ) T{}; },
(void* ptr){ static_cast<T*>(ptr)->~T(); }
);
if (!smart_ptr)
exit(-1); // or throw something
return *static_cast<T*>(smart_ptr.get());
}
protected:
singleton() = default;
~singleton() = default;
private:
singleton(singleton&&) = delete;
singleton& operator=(singleton&&) = delete;
};


use looks like:



struct Logger : LibSingleton::singleton<Logger> {
friend class LibSingleton::singleton<Logger>;
void do_log( char const* sting ) {}
private:
Logger() { /* ... */ }
};





share|improve this answer





















  • 4





    Makes one wonder if having a Singleton is worth all that effort...

    – Jared Smith
    Apr 2 at 15:14






  • 1





    It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

    – David K
    Apr 2 at 19:56





















2














Here's an idea:Rather than use a singleton,which is both a hard problem in your environment and known to be problematic for testing and maintenance,just design your code to only create one of the object in question.






share|improve this answer








New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 7





    Don't disagree, but this answer would be improved by an explanation of how...

    – Jared Smith
    Apr 2 at 15:15



















2














Make it a global variable in a source file. That way you will only have one definition, even with static linking:




Anything wrong with my singleton design? Is it a thread-safe issue?




"Kind of" to the former, "No" for the latter




Seems like my singleton works fine in one so scope, but each so lib which include my singleton will create its own singleton, so that my singleton is no longer “be a singleton”. Is the problem caused from each dynamic linking to new so and the "staic veriable" become "local static"? Is it possible? If so, how to fix




If your GetInstance call is actually inlined it gives the compiler a free pass to create multiple definitions. If you declare it in a source file it will still cause trouble if you link against it as a static library multiple times.



This code should work



// Logger.cpp

Logger* gLoggerInstance = nullptr; // NOT STATIC
std::mutex gLoggerInstanceLock; // NOT STATIC, only if you need thread-safety

Logger& Logger::GetInstance() {
std::lock_guard(loggerInstanceLock); // only if you need thread-safety
if(!loggerInstance) loggerInstance = new Logger();
return *loggerInstance;
}


Edit: Only doesn't work with static libraries if you link the static libs into multiple DLLs that you then link into your executable:



A.lib
|
X.dll Y.dll
| /
G.exe





share|improve this answer





















  • 1





    this will not work because each static lib has its own copy of global and static variables.

    – hismart
    Apr 3 at 7:39



















0














static variable should be moved to .cpp file.



Simple way is to keep only declaration of getInstance() in .h and move implementation to .cpp file.






share|improve this answer



















  • 5





    That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

    – Angew
    Apr 2 at 12:39



















-2














It may be that your header file is being defined multiple times (it's the case if multiple files are including this header file. Try adding a guard around the header file to prevent it from being re-defined if it has already been defined once.



Depending on your C++ compiler, you could actually just add #pragma once as the first line in your file, like this



#pragma once
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


The intended effect is that of the most general alternative, which is to add a macro definition like this



#ifndef LOGGER_H
#define LOGGER_H
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}
#endif LOGGER_H





share|improve this answer





















  • 6





    Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

    – user4581301
    Apr 2 at 5:15






  • 1





    Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

    – hismart
    Apr 2 at 5:20






  • 1





    1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

    – Benno Straub
    Apr 2 at 11:35














Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55467246%2fmy-singleton-can-be-called-multiple-times%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























6 Answers
6






active

oldest

votes








6 Answers
6






active

oldest

votes









active

oldest

votes






active

oldest

votes









28
















  1. Anything wrong with my singleton design? Is it a thread-safe issue?




No. Initialization of function local static variables is guaranteed to be thread-safe by the standard.





  1. Seems like my singleton works fine in one so scope, but each
    so lib which include my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "staic veriable" become "local static"?
    Is it possible? If so, how to fix




That is the correct conclusion.



Instead of creating a static library that contains the implementation of the singleton, make it a dynamic library.






share|improve this answer
























  • Thanks a lot for the help. Finally I change to use dynamic linking and works fine

    – hismart
    Apr 3 at 9:58











  • @hismart, you are welcome. Glad I was able to help.

    – R Sahu
    Apr 3 at 18:12
















28
















  1. Anything wrong with my singleton design? Is it a thread-safe issue?




No. Initialization of function local static variables is guaranteed to be thread-safe by the standard.





  1. Seems like my singleton works fine in one so scope, but each
    so lib which include my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "staic veriable" become "local static"?
    Is it possible? If so, how to fix




That is the correct conclusion.



Instead of creating a static library that contains the implementation of the singleton, make it a dynamic library.






share|improve this answer
























  • Thanks a lot for the help. Finally I change to use dynamic linking and works fine

    – hismart
    Apr 3 at 9:58











  • @hismart, you are welcome. Glad I was able to help.

    – R Sahu
    Apr 3 at 18:12














28












28








28









  1. Anything wrong with my singleton design? Is it a thread-safe issue?




No. Initialization of function local static variables is guaranteed to be thread-safe by the standard.





  1. Seems like my singleton works fine in one so scope, but each
    so lib which include my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "staic veriable" become "local static"?
    Is it possible? If so, how to fix




That is the correct conclusion.



Instead of creating a static library that contains the implementation of the singleton, make it a dynamic library.






share|improve this answer















  1. Anything wrong with my singleton design? Is it a thread-safe issue?




No. Initialization of function local static variables is guaranteed to be thread-safe by the standard.





  1. Seems like my singleton works fine in one so scope, but each
    so lib which include my singleton will create its own singleton, so that my
    singleton is no longer “be a singleton”. Is the problem caused from each
    dynamic linking to new so and the "staic veriable" become "local static"?
    Is it possible? If so, how to fix




That is the correct conclusion.



Instead of creating a static library that contains the implementation of the singleton, make it a dynamic library.







share|improve this answer












share|improve this answer



share|improve this answer










answered Apr 2 at 5:08









R SahuR Sahu

171k1297195




171k1297195













  • Thanks a lot for the help. Finally I change to use dynamic linking and works fine

    – hismart
    Apr 3 at 9:58











  • @hismart, you are welcome. Glad I was able to help.

    – R Sahu
    Apr 3 at 18:12



















  • Thanks a lot for the help. Finally I change to use dynamic linking and works fine

    – hismart
    Apr 3 at 9:58











  • @hismart, you are welcome. Glad I was able to help.

    – R Sahu
    Apr 3 at 18:12

















Thanks a lot for the help. Finally I change to use dynamic linking and works fine

– hismart
Apr 3 at 9:58





Thanks a lot for the help. Finally I change to use dynamic linking and works fine

– hismart
Apr 3 at 9:58













@hismart, you are welcome. Glad I was able to help.

– R Sahu
Apr 3 at 18:12





@hismart, you are welcome. Glad I was able to help.

– R Sahu
Apr 3 at 18:12













4














Singletons are hard, especially with shared libraries.



Each of your shared libraries has an independent copy of the non-shared library. Without extra care, each will have a copy of the singleton.



In order to have non-trivial singletons, what I have had to do was




  1. Create an extremely low level library to help with singletons -- call it LibSingleton


  2. Create a singleton template that knows the type of the singleton. It uses magic statics to send a request to the LibSingleton with a size, typeid(T).name() key, and type-erased construction and destruction code. LibSingleton returns a reference counting RAII object.


  3. LibSingleton uses a shared mutex to either return a previously constructed object that matches the name/size or constructs it. If it constructs the object, it stores the destruction code.


  4. When the last reference-counted handle to the LibSingleton data goes away, LibSingleton runs the destruction code and cleans up the memory in its unordered map.



This permits really simple singletons to be used nearly anywhere.



template<class T>
class singleton {
public:
static T& Instance() {
static auto smart_ptr = LibSingleton::RequestInstance(
typeid(T).name(),
sizeof(T),
(void* ptr){ return ::new( ptr ) T{}; },
(void* ptr){ static_cast<T*>(ptr)->~T(); }
);
if (!smart_ptr)
exit(-1); // or throw something
return *static_cast<T*>(smart_ptr.get());
}
protected:
singleton() = default;
~singleton() = default;
private:
singleton(singleton&&) = delete;
singleton& operator=(singleton&&) = delete;
};


use looks like:



struct Logger : LibSingleton::singleton<Logger> {
friend class LibSingleton::singleton<Logger>;
void do_log( char const* sting ) {}
private:
Logger() { /* ... */ }
};





share|improve this answer





















  • 4





    Makes one wonder if having a Singleton is worth all that effort...

    – Jared Smith
    Apr 2 at 15:14






  • 1





    It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

    – David K
    Apr 2 at 19:56


















4














Singletons are hard, especially with shared libraries.



Each of your shared libraries has an independent copy of the non-shared library. Without extra care, each will have a copy of the singleton.



In order to have non-trivial singletons, what I have had to do was




  1. Create an extremely low level library to help with singletons -- call it LibSingleton


  2. Create a singleton template that knows the type of the singleton. It uses magic statics to send a request to the LibSingleton with a size, typeid(T).name() key, and type-erased construction and destruction code. LibSingleton returns a reference counting RAII object.


  3. LibSingleton uses a shared mutex to either return a previously constructed object that matches the name/size or constructs it. If it constructs the object, it stores the destruction code.


  4. When the last reference-counted handle to the LibSingleton data goes away, LibSingleton runs the destruction code and cleans up the memory in its unordered map.



This permits really simple singletons to be used nearly anywhere.



template<class T>
class singleton {
public:
static T& Instance() {
static auto smart_ptr = LibSingleton::RequestInstance(
typeid(T).name(),
sizeof(T),
(void* ptr){ return ::new( ptr ) T{}; },
(void* ptr){ static_cast<T*>(ptr)->~T(); }
);
if (!smart_ptr)
exit(-1); // or throw something
return *static_cast<T*>(smart_ptr.get());
}
protected:
singleton() = default;
~singleton() = default;
private:
singleton(singleton&&) = delete;
singleton& operator=(singleton&&) = delete;
};


use looks like:



struct Logger : LibSingleton::singleton<Logger> {
friend class LibSingleton::singleton<Logger>;
void do_log( char const* sting ) {}
private:
Logger() { /* ... */ }
};





share|improve this answer





















  • 4





    Makes one wonder if having a Singleton is worth all that effort...

    – Jared Smith
    Apr 2 at 15:14






  • 1





    It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

    – David K
    Apr 2 at 19:56
















4












4








4







Singletons are hard, especially with shared libraries.



Each of your shared libraries has an independent copy of the non-shared library. Without extra care, each will have a copy of the singleton.



In order to have non-trivial singletons, what I have had to do was




  1. Create an extremely low level library to help with singletons -- call it LibSingleton


  2. Create a singleton template that knows the type of the singleton. It uses magic statics to send a request to the LibSingleton with a size, typeid(T).name() key, and type-erased construction and destruction code. LibSingleton returns a reference counting RAII object.


  3. LibSingleton uses a shared mutex to either return a previously constructed object that matches the name/size or constructs it. If it constructs the object, it stores the destruction code.


  4. When the last reference-counted handle to the LibSingleton data goes away, LibSingleton runs the destruction code and cleans up the memory in its unordered map.



This permits really simple singletons to be used nearly anywhere.



template<class T>
class singleton {
public:
static T& Instance() {
static auto smart_ptr = LibSingleton::RequestInstance(
typeid(T).name(),
sizeof(T),
(void* ptr){ return ::new( ptr ) T{}; },
(void* ptr){ static_cast<T*>(ptr)->~T(); }
);
if (!smart_ptr)
exit(-1); // or throw something
return *static_cast<T*>(smart_ptr.get());
}
protected:
singleton() = default;
~singleton() = default;
private:
singleton(singleton&&) = delete;
singleton& operator=(singleton&&) = delete;
};


use looks like:



struct Logger : LibSingleton::singleton<Logger> {
friend class LibSingleton::singleton<Logger>;
void do_log( char const* sting ) {}
private:
Logger() { /* ... */ }
};





share|improve this answer















Singletons are hard, especially with shared libraries.



Each of your shared libraries has an independent copy of the non-shared library. Without extra care, each will have a copy of the singleton.



In order to have non-trivial singletons, what I have had to do was




  1. Create an extremely low level library to help with singletons -- call it LibSingleton


  2. Create a singleton template that knows the type of the singleton. It uses magic statics to send a request to the LibSingleton with a size, typeid(T).name() key, and type-erased construction and destruction code. LibSingleton returns a reference counting RAII object.


  3. LibSingleton uses a shared mutex to either return a previously constructed object that matches the name/size or constructs it. If it constructs the object, it stores the destruction code.


  4. When the last reference-counted handle to the LibSingleton data goes away, LibSingleton runs the destruction code and cleans up the memory in its unordered map.



This permits really simple singletons to be used nearly anywhere.



template<class T>
class singleton {
public:
static T& Instance() {
static auto smart_ptr = LibSingleton::RequestInstance(
typeid(T).name(),
sizeof(T),
(void* ptr){ return ::new( ptr ) T{}; },
(void* ptr){ static_cast<T*>(ptr)->~T(); }
);
if (!smart_ptr)
exit(-1); // or throw something
return *static_cast<T*>(smart_ptr.get());
}
protected:
singleton() = default;
~singleton() = default;
private:
singleton(singleton&&) = delete;
singleton& operator=(singleton&&) = delete;
};


use looks like:



struct Logger : LibSingleton::singleton<Logger> {
friend class LibSingleton::singleton<Logger>;
void do_log( char const* sting ) {}
private:
Logger() { /* ... */ }
};






share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 2 at 16:04

























answered Apr 2 at 14:36









Yakk - Adam NevraumontYakk - Adam Nevraumont

189k21199384




189k21199384








  • 4





    Makes one wonder if having a Singleton is worth all that effort...

    – Jared Smith
    Apr 2 at 15:14






  • 1





    It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

    – David K
    Apr 2 at 19:56
















  • 4





    Makes one wonder if having a Singleton is worth all that effort...

    – Jared Smith
    Apr 2 at 15:14






  • 1





    It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

    – David K
    Apr 2 at 19:56










4




4





Makes one wonder if having a Singleton is worth all that effort...

– Jared Smith
Apr 2 at 15:14





Makes one wonder if having a Singleton is worth all that effort...

– Jared Smith
Apr 2 at 15:14




1




1





It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

– David K
Apr 2 at 19:56







It looks like most of the effort is spent to get the first singleton, and others are relatively easy to add. Still, it makes one wonder ...

– David K
Apr 2 at 19:56













2














Here's an idea:Rather than use a singleton,which is both a hard problem in your environment and known to be problematic for testing and maintenance,just design your code to only create one of the object in question.






share|improve this answer








New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 7





    Don't disagree, but this answer would be improved by an explanation of how...

    – Jared Smith
    Apr 2 at 15:15
















2














Here's an idea:Rather than use a singleton,which is both a hard problem in your environment and known to be problematic for testing and maintenance,just design your code to only create one of the object in question.






share|improve this answer








New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 7





    Don't disagree, but this answer would be improved by an explanation of how...

    – Jared Smith
    Apr 2 at 15:15














2












2








2







Here's an idea:Rather than use a singleton,which is both a hard problem in your environment and known to be problematic for testing and maintenance,just design your code to only create one of the object in question.






share|improve this answer








New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










Here's an idea:Rather than use a singleton,which is both a hard problem in your environment and known to be problematic for testing and maintenance,just design your code to only create one of the object in question.







share|improve this answer








New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this answer



share|improve this answer






New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









answered Apr 2 at 14:18









Life SchoolLife School

213




213




New contributor




Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Life School is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 7





    Don't disagree, but this answer would be improved by an explanation of how...

    – Jared Smith
    Apr 2 at 15:15














  • 7





    Don't disagree, but this answer would be improved by an explanation of how...

    – Jared Smith
    Apr 2 at 15:15








7




7





Don't disagree, but this answer would be improved by an explanation of how...

– Jared Smith
Apr 2 at 15:15





Don't disagree, but this answer would be improved by an explanation of how...

– Jared Smith
Apr 2 at 15:15











2














Make it a global variable in a source file. That way you will only have one definition, even with static linking:




Anything wrong with my singleton design? Is it a thread-safe issue?




"Kind of" to the former, "No" for the latter




Seems like my singleton works fine in one so scope, but each so lib which include my singleton will create its own singleton, so that my singleton is no longer “be a singleton”. Is the problem caused from each dynamic linking to new so and the "staic veriable" become "local static"? Is it possible? If so, how to fix




If your GetInstance call is actually inlined it gives the compiler a free pass to create multiple definitions. If you declare it in a source file it will still cause trouble if you link against it as a static library multiple times.



This code should work



// Logger.cpp

Logger* gLoggerInstance = nullptr; // NOT STATIC
std::mutex gLoggerInstanceLock; // NOT STATIC, only if you need thread-safety

Logger& Logger::GetInstance() {
std::lock_guard(loggerInstanceLock); // only if you need thread-safety
if(!loggerInstance) loggerInstance = new Logger();
return *loggerInstance;
}


Edit: Only doesn't work with static libraries if you link the static libs into multiple DLLs that you then link into your executable:



A.lib
|
X.dll Y.dll
| /
G.exe





share|improve this answer





















  • 1





    this will not work because each static lib has its own copy of global and static variables.

    – hismart
    Apr 3 at 7:39
















2














Make it a global variable in a source file. That way you will only have one definition, even with static linking:




Anything wrong with my singleton design? Is it a thread-safe issue?




"Kind of" to the former, "No" for the latter




Seems like my singleton works fine in one so scope, but each so lib which include my singleton will create its own singleton, so that my singleton is no longer “be a singleton”. Is the problem caused from each dynamic linking to new so and the "staic veriable" become "local static"? Is it possible? If so, how to fix




If your GetInstance call is actually inlined it gives the compiler a free pass to create multiple definitions. If you declare it in a source file it will still cause trouble if you link against it as a static library multiple times.



This code should work



// Logger.cpp

Logger* gLoggerInstance = nullptr; // NOT STATIC
std::mutex gLoggerInstanceLock; // NOT STATIC, only if you need thread-safety

Logger& Logger::GetInstance() {
std::lock_guard(loggerInstanceLock); // only if you need thread-safety
if(!loggerInstance) loggerInstance = new Logger();
return *loggerInstance;
}


Edit: Only doesn't work with static libraries if you link the static libs into multiple DLLs that you then link into your executable:



A.lib
|
X.dll Y.dll
| /
G.exe





share|improve this answer





















  • 1





    this will not work because each static lib has its own copy of global and static variables.

    – hismart
    Apr 3 at 7:39














2












2








2







Make it a global variable in a source file. That way you will only have one definition, even with static linking:




Anything wrong with my singleton design? Is it a thread-safe issue?




"Kind of" to the former, "No" for the latter




Seems like my singleton works fine in one so scope, but each so lib which include my singleton will create its own singleton, so that my singleton is no longer “be a singleton”. Is the problem caused from each dynamic linking to new so and the "staic veriable" become "local static"? Is it possible? If so, how to fix




If your GetInstance call is actually inlined it gives the compiler a free pass to create multiple definitions. If you declare it in a source file it will still cause trouble if you link against it as a static library multiple times.



This code should work



// Logger.cpp

Logger* gLoggerInstance = nullptr; // NOT STATIC
std::mutex gLoggerInstanceLock; // NOT STATIC, only if you need thread-safety

Logger& Logger::GetInstance() {
std::lock_guard(loggerInstanceLock); // only if you need thread-safety
if(!loggerInstance) loggerInstance = new Logger();
return *loggerInstance;
}


Edit: Only doesn't work with static libraries if you link the static libs into multiple DLLs that you then link into your executable:



A.lib
|
X.dll Y.dll
| /
G.exe





share|improve this answer















Make it a global variable in a source file. That way you will only have one definition, even with static linking:




Anything wrong with my singleton design? Is it a thread-safe issue?




"Kind of" to the former, "No" for the latter




Seems like my singleton works fine in one so scope, but each so lib which include my singleton will create its own singleton, so that my singleton is no longer “be a singleton”. Is the problem caused from each dynamic linking to new so and the "staic veriable" become "local static"? Is it possible? If so, how to fix




If your GetInstance call is actually inlined it gives the compiler a free pass to create multiple definitions. If you declare it in a source file it will still cause trouble if you link against it as a static library multiple times.



This code should work



// Logger.cpp

Logger* gLoggerInstance = nullptr; // NOT STATIC
std::mutex gLoggerInstanceLock; // NOT STATIC, only if you need thread-safety

Logger& Logger::GetInstance() {
std::lock_guard(loggerInstanceLock); // only if you need thread-safety
if(!loggerInstance) loggerInstance = new Logger();
return *loggerInstance;
}


Edit: Only doesn't work with static libraries if you link the static libs into multiple DLLs that you then link into your executable:



A.lib
|
X.dll Y.dll
| /
G.exe






share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 3 at 7:55

























answered Apr 2 at 11:52









Benno StraubBenno Straub

40879




40879








  • 1





    this will not work because each static lib has its own copy of global and static variables.

    – hismart
    Apr 3 at 7:39














  • 1





    this will not work because each static lib has its own copy of global and static variables.

    – hismart
    Apr 3 at 7:39








1




1





this will not work because each static lib has its own copy of global and static variables.

– hismart
Apr 3 at 7:39





this will not work because each static lib has its own copy of global and static variables.

– hismart
Apr 3 at 7:39











0














static variable should be moved to .cpp file.



Simple way is to keep only declaration of getInstance() in .h and move implementation to .cpp file.






share|improve this answer



















  • 5





    That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

    – Angew
    Apr 2 at 12:39
















0














static variable should be moved to .cpp file.



Simple way is to keep only declaration of getInstance() in .h and move implementation to .cpp file.






share|improve this answer



















  • 5





    That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

    – Angew
    Apr 2 at 12:39














0












0








0







static variable should be moved to .cpp file.



Simple way is to keep only declaration of getInstance() in .h and move implementation to .cpp file.






share|improve this answer













static variable should be moved to .cpp file.



Simple way is to keep only declaration of getInstance() in .h and move implementation to .cpp file.







share|improve this answer












share|improve this answer



share|improve this answer










answered Apr 2 at 7:52









AIMIN PANAIMIN PAN

295210




295210








  • 5





    That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

    – Angew
    Apr 2 at 12:39














  • 5





    That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

    – Angew
    Apr 2 at 12:39








5




5





That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

– Angew
Apr 2 at 12:39





That won't help at all. Even inline functions are guaranteed to have only one set of statics. The problem here is with the shared libraries.

– Angew
Apr 2 at 12:39











-2














It may be that your header file is being defined multiple times (it's the case if multiple files are including this header file. Try adding a guard around the header file to prevent it from being re-defined if it has already been defined once.



Depending on your C++ compiler, you could actually just add #pragma once as the first line in your file, like this



#pragma once
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


The intended effect is that of the most general alternative, which is to add a macro definition like this



#ifndef LOGGER_H
#define LOGGER_H
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}
#endif LOGGER_H





share|improve this answer





















  • 6





    Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

    – user4581301
    Apr 2 at 5:15






  • 1





    Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

    – hismart
    Apr 2 at 5:20






  • 1





    1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

    – Benno Straub
    Apr 2 at 11:35


















-2














It may be that your header file is being defined multiple times (it's the case if multiple files are including this header file. Try adding a guard around the header file to prevent it from being re-defined if it has already been defined once.



Depending on your C++ compiler, you could actually just add #pragma once as the first line in your file, like this



#pragma once
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


The intended effect is that of the most general alternative, which is to add a macro definition like this



#ifndef LOGGER_H
#define LOGGER_H
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}
#endif LOGGER_H





share|improve this answer





















  • 6





    Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

    – user4581301
    Apr 2 at 5:15






  • 1





    Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

    – hismart
    Apr 2 at 5:20






  • 1





    1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

    – Benno Straub
    Apr 2 at 11:35
















-2












-2








-2







It may be that your header file is being defined multiple times (it's the case if multiple files are including this header file. Try adding a guard around the header file to prevent it from being re-defined if it has already been defined once.



Depending on your C++ compiler, you could actually just add #pragma once as the first line in your file, like this



#pragma once
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


The intended effect is that of the most general alternative, which is to add a macro definition like this



#ifndef LOGGER_H
#define LOGGER_H
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}
#endif LOGGER_H





share|improve this answer















It may be that your header file is being defined multiple times (it's the case if multiple files are including this header file. Try adding a guard around the header file to prevent it from being re-defined if it has already been defined once.



Depending on your C++ compiler, you could actually just add #pragma once as the first line in your file, like this



#pragma once
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}


The intended effect is that of the most general alternative, which is to add a macro definition like this



#ifndef LOGGER_H
#define LOGGER_H
class Logger
{
public:

/// Return the singleton instance of Logger
static Logger& GetInstance() {
static Logger s_loggerSingleton;
return s_loggerSingleton;
}

private:

/// Constructor
Logger();
/// Destructor
~Logger();
}
#endif LOGGER_H






share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 2 at 5:19

























answered Apr 2 at 5:08









ribbitribbit

399311




399311








  • 6





    Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

    – user4581301
    Apr 2 at 5:15






  • 1





    Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

    – hismart
    Apr 2 at 5:20






  • 1





    1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

    – Benno Straub
    Apr 2 at 11:35
















  • 6





    Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

    – user4581301
    Apr 2 at 5:15






  • 1





    Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

    – hismart
    Apr 2 at 5:20






  • 1





    1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

    – Benno Straub
    Apr 2 at 11:35










6




6





Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

– user4581301
Apr 2 at 5:15





Minor niggle: If you're using C++, you can just add #pragma once should be If you're using one of many common C++ compilers, you can just add #pragma once. When #pragma once has universal, Standard guaranteed support it will become #once.

– user4581301
Apr 2 at 5:15




1




1





Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

– hismart
Apr 2 at 5:20





Thanks for your hint. I already add the define but forgot to post it in here! I use your second solution.

– hismart
Apr 2 at 5:20




1




1





1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

– Benno Straub
Apr 2 at 11:35







1. If that was the issue it would not compile ("redeclared class Logger") 2. This will not prevent multiple definitions of the static variable

– Benno Straub
Apr 2 at 11:35




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55467246%2fmy-singleton-can-be-called-multiple-times%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Plaza Victoria

Brian Clough

Cáceres