Singleton Object Management

3,346 views
3,224 views

Published on

This is from my series of presentations on C++ and Design Pattern. This was first presented at Interra in 2005.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
3,346
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
35
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Singleton Object Management

  1. 1. November 7, 2005 Singleton Object Management Dr. Partha Pratim Das Interra Systems (India) Pvt. Ltd. Resource Management Series
  2. 2. Agenda <ul><li>Backgrounder </li></ul><ul><ul><li>atexit() behavior </li></ul></ul><ul><ul><li>Object Lifetime </li></ul></ul><ul><li>Singleton Class </li></ul><ul><ul><li>What?, Why? & How? </li></ul></ul><ul><ul><li>A simple singleton </li></ul></ul><ul><ul><ul><li>How to enforce singleton discipline </li></ul></ul></ul><ul><ul><li>Meyer’s Singleton </li></ul></ul><ul><ul><ul><li>The Dead Reference Problem </li></ul></ul></ul><ul><ul><li>The Phoenix Singleton </li></ul></ul><ul><li>Q&A </li></ul>
  3. 3. Backgrounder Object Lifetime
  4. 4. atexit() Callback Behavior – Execute code after main() <ul><li>atexit() signature </li></ul><ul><ul><ul><li>int atexit(void (*pFunction)(void)); </li></ul></ul></ul><ul><ul><ul><li>// 0 is success </li></ul></ul></ul><ul><li>Use atexit() to register any function having the following signature </li></ul><ul><ul><ul><li>void CallbackFunction(void); </li></ul></ul></ul><ul><li>The registered function will be called from the runtime system after main() exits </li></ul><ul><li>If multiple functions are registered, then the calls will made be in the reverse order of registration (LIFO) </li></ul><ul><li>Used by: </li></ul><ul><ul><li>Compiler for </li></ul></ul><ul><ul><ul><li>Local Static Objects </li></ul></ul></ul><ul><ul><li>Application Programmer for any function call beyond main() </li></ul></ul>
  5. 5. atexit() Callback Behavior <ul><li>Note: </li></ul><ul><ul><li>Executing return from main() or direct call to exit(.) invokes all callbacks registered with atexit() before the control actually exits (global destructors are called). </li></ul></ul><ul><ul><li>Call to abort() bypasses callbacks. </li></ul></ul><ul><ul><li>atexit() registration from within a Callback function may have unspecified behavior. </li></ul></ul>
  6. 6. Object Lifetime <ul><li>Starts with Constructor execution </li></ul><ul><ul><li>Must follow Memory Allocation </li></ul></ul><ul><li>Ends with Destructor execution </li></ul><ul><ul><li>Must precede Memory De-allocation </li></ul></ul><ul><li>For Built-in Types (w/o Constructor / Destructor) the notion follows the same pattern though the compiler actually optimizes the creation / destruction processes. </li></ul>
  7. 7. Object Lifetime <ul><li>Automatic Object – Function / Block Scope </li></ul><ul><ul><li>Space allocated on stack when (just before) the control enters the scope </li></ul></ul><ul><ul><li>Object created (and initialized) when the control passes the declaration </li></ul></ul><ul><ul><li>Object destroyed when (just after) the control leaves the scope </li></ul></ul><ul><ul><li>Objects (within a scope) are destroyed in the reverse order of creations </li></ul></ul><ul><ul><li>Space de-allocated after all automatic objects have been destructed. </li></ul></ul>
  8. 8. Object Lifetime <ul><li>Non-static member Object – Class Scope </li></ul><ul><ul><li>Constructed in the initialization list of the Constructor of the Parent Object </li></ul></ul><ul><ul><ul><li>Before the first statement of the constructor executes </li></ul></ul></ul><ul><ul><li>Follows the lexical order of declarations in the class </li></ul></ul><ul><ul><li>Destructed by the Destructor of the Parent Object </li></ul></ul><ul><ul><ul><li>After the last statement of the destructor executes </li></ul></ul></ul>
  9. 9. Object Lifetime <ul><li>Free Store Object </li></ul><ul><ul><li>Lifetime controlled by the user </li></ul></ul><ul><ul><li>Constructor called by operator new </li></ul></ul><ul><ul><ul><li>Must follow Memory Allocation </li></ul></ul></ul><ul><ul><li>Destructor called by operator delete </li></ul></ul><ul><ul><ul><li>Must precede Memory De-allocation </li></ul></ul></ul>
  10. 10. Object Lifetime <ul><li>Static Object – Global / Class Scope </li></ul><ul><ul><li>Built-in Type – no constructor / destructor </li></ul></ul><ul><ul><ul><li>Object created (and initialized) implicitly when the program is loaded </li></ul></ul></ul><ul><ul><ul><ul><li>before first assembly instruction in main() </li></ul></ul></ul></ul><ul><ul><ul><ul><li>actually before any global object of user-defined type is constructed </li></ul></ul></ul></ul><ul><ul><ul><li>Object destroyed implicitly before the program is unloaded </li></ul></ul></ul><ul><ul><ul><ul><li>after last assembly instruction in main() </li></ul></ul></ul></ul><ul><ul><ul><ul><li>actually after all global objects of user-defined type are destructed </li></ul></ul></ul></ul><ul><ul><ul><li>Has no boundary for translation units – literally “load time” </li></ul></ul></ul><ul><ul><ul><li>Has no executable code in construction / destruction . </li></ul></ul></ul>
  11. 11. Object Lifetime <ul><li>Static Object – Global / Class Scope </li></ul><ul><ul><li>User-Defined Types </li></ul></ul><ul><ul><ul><li>Space allocation is done at “load-time”. </li></ul></ul></ul><ul><ul><ul><li>Allocated space is zero-filled </li></ul></ul></ul><ul><ul><ul><li>Object created (and initialized) sequentially within a translation unit </li></ul></ul></ul><ul><ul><ul><li>Creation order between different translation units is arbitrary </li></ul></ul></ul><ul><ul><ul><ul><li>Some iostreams objects are properly initialized for use by the static constructors. These control text streams – cin, cout, cerr, clog </li></ul></ul></ul></ul><ul><ul><ul><li>Destroyed in the reverse order of creations – creation order is static </li></ul></ul></ul><ul><ul><ul><ul><li>iostreams objects can be used within the destructors called for static objects, during program termination. </li></ul></ul></ul></ul>
  12. 12. Object Lifetime <ul><li>Static Object – Function / Local Scope </li></ul><ul><ul><li>Built-in Type </li></ul></ul><ul><ul><ul><li>Same as static objects in Global / Class Scope </li></ul></ul></ul><ul><ul><li>User-Defined Types </li></ul></ul><ul><ul><ul><li>Object created (and initialized) when the control passes the declaration for the first time </li></ul></ul></ul><ul><ul><ul><li>Destroyed in the reverse order of creations (LIFO) </li></ul></ul></ul><ul><ul><ul><ul><li>after last assembly instruction in main() </li></ul></ul></ul></ul><ul><ul><ul><ul><li>before the global objects of user-defined type are destructed </li></ul></ul></ul></ul><ul><ul><ul><li>Uses atexit() – because the creation order is dynamic </li></ul></ul></ul>
  13. 13. Static Object Lifetime An Example
  14. 18. Output: VC 6.0
  15. 19. Output: VC 7.1
  16. 20. Singleton Objects What and Why
  17. 21. What is a Singleton Class? <ul><li>A class is a singleton if </li></ul><ul><ul><li>It has only one instance, and </li></ul></ul><ul><ul><li>Global point of access to the singular instance </li></ul></ul><ul><ul><li>Can be accessed anytime during the application </li></ul></ul><ul><li>“ Global point of access” – Implications </li></ul><ul><ul><li>Singleton object “owns” itself </li></ul></ul><ul><ul><li>No client step to create singletons </li></ul></ul><ul><ul><li>Creates and Destroys itself. </li></ul></ul><ul><li>Singleton is a Design Pattern </li></ul><ul><li>A singleton is an improved global variable </li></ul>
  18. 22. Lifetime Semantics for a Singleton <ul><li>A single object of a class stays throughout the lifetime of an application </li></ul><ul><ul><li>Created when the execution of the program “starts” and remains there till the application “ends” </li></ul></ul><ul><li>The Singleton class is instantiated at the time of first access and same instance is used thereafter till the application quits. </li></ul><ul><li>At no point during execution there is more than one instance of the class; but in between it may be created & destroyed several times. </li></ul><ul><ul><li>There are execution points where no object exists. </li></ul></ul>
  19. 23. Singleton Examples <ul><li>The office of the President of India is a Singleton. </li></ul><ul><ul><li>The constitution specifies the means by which a President is selected, limits the term of office, and defines the order of succession. </li></ul></ul><ul><ul><li>There can be at most one President at any given time. </li></ul></ul><ul><ul><li>There will be exactly one at any given time. </li></ul></ul><ul><ul><li>Regardless of the personal identity of the President, the title, “President of India&quot; is a global point of access that identifies the person in the office. </li></ul></ul>
  20. 24. Singleton Examples <ul><li>Purify license in a network can be a Singleton. </li></ul><ul><ul><li>A Singleton connection objects can ensure that only one connection can be made at any time. </li></ul></ul><ul><li>Printer can be a singleton in a network. </li></ul><ul><li>Keyboard, Display, Log, … </li></ul><ul><li>[MFC] – The global instance of the CWinApp-derived application class is the singleton. </li></ul><ul><li>In EDAObjects™ </li></ul><ul><ul><li>Memory Manager </li></ul></ul><ul><ul><li>Message Handler </li></ul></ul><ul><ul><li>Command Line Processor </li></ul></ul>
  21. 25. Singleton Implementation How
  22. 26. Static Data + Static Function != Singleton <ul><li>Wrap the Singleton object and function that uses the object within a class </li></ul><ul><li>Make both static </li></ul><ul><li>Keep the object private and the method public </li></ul><ul><li>This is not a “good” singleton because </li></ul><ul><ul><li>static methods cannot be virtual </li></ul></ul><ul><ul><li>Initialization and Clean-up is difficult </li></ul></ul><ul><ul><li>There is no unique point of access </li></ul></ul>
  23. 27. Essence of Singleton Implementation <ul><li>To make a class singleton </li></ul><ul><ul><li>Make all constructors private </li></ul></ul><ul><ul><li>Provide a static method as a unique access point for the singleton. </li></ul></ul><ul><li>Examples follow … </li></ul>
  24. 28. A Simple Singleton
  25. 29. A Simple Singleton <ul><li>A simple – no-frills singleton is illustrated </li></ul><ul><li>Singleton is dynamically created </li></ul><ul><ul><li>a static creation may cause conflict in creation order </li></ul></ul><ul><li>Does not have a proper destruction point </li></ul><ul><ul><li>Cannot delete from within main() since some global objects may be using it </li></ul></ul><ul><ul><li>Hence the singleton leaks </li></ul></ul><ul><ul><ul><li>Is it a memory leak? </li></ul></ul></ul><ul><ul><ul><li>Is it a resource leak? </li></ul></ul></ul>
  26. 30. Meyer’s Singleton – A Solution <ul><li>Create the singleton as a local static object </li></ul><ul><li>Will be destroyed at exit </li></ul><ul><li>Does it solve all problems? </li></ul>Singleton& Singleton::Instance() { static Singleton theInstance; return theInstance; }
  27. 31. The Dead Reference Problem <ul><li>There are 3 singletons – </li></ul><ul><ul><li>Keyboard, </li></ul></ul><ul><ul><li>Display and </li></ul></ul><ul><ul><li>Log </li></ul></ul><ul><ul><ul><li>Error Reporting </li></ul></ul></ul><ul><ul><ul><li>Created on-demand </li></ul></ul></ul><ul><li>All are implemented by Meyer’s Singleton </li></ul><ul><li>Consider an exception scenario … </li></ul>
  28. 32. The Dead Reference Scenario <ul><li>Keyboard successfully created </li></ul><ul><li>Display fails to initialize </li></ul><ul><li>Log created </li></ul><ul><li>Error logged; application proceeds to exit </li></ul><ul><li>Log destroyed (LIFO order) </li></ul><ul><li>Keyboard fails to shutdown </li></ul><ul><li>Log::Instance() invoked for error reporting </li></ul><ul><ul><li>Returns a dead object!!! </li></ul></ul>
  29. 33. The Dead Reference Detection <ul><li>Maintain a flag with every singleton that tells if the singleton is alive. </li></ul><ul><li>If a dead reference is detected, an exceptions is raised. </li></ul><ul><li>The code follows … </li></ul>
  30. 34. Meyer’s Singleton with Dead Reference Detection
  31. 35. Phoenix Singleton <ul><li>Like Phoenix bird, this singleton rises repeatedly from its ashes </li></ul><ul><li>Outline </li></ul><ul><ul><li>Retrieve the Caracas (this a global allocation) </li></ul></ul><ul><ul><li>Reincarnate the singleton </li></ul></ul><ul><ul><li>Register a callback for destruction with atexit() </li></ul></ul>
  32. 36. Phoenix Singleton
  33. 37. More Singletons … <ul><li>Explicit Management of Lifetime with user-assigned priorities (Longevity Control) </li></ul><ul><li>Singletons under multi-threading </li></ul><ul><li>Singleton template </li></ul><ul><li>Singletons in Java, C# and .NET </li></ul>
  34. 38. Singletons in C++ References & Credits
  35. 39. References: Books <ul><li>Modern C++ Design: Generic Programming & Design Pattern Applied by Andrei Alexandrescu , Pearson Education 2001 </li></ul><ul><ul><li>Most of the material from “Implementing Singletons” chapter </li></ul></ul><ul><li>Exceptional C++ by Herb Sutter </li></ul><ul><ul><li>Discussion on Object Lifetime </li></ul></ul><ul><li>Effective C++ & More Effective C++: by Scott Meyers </li></ul><ul><ul><li>Many items relating to Object lifetime & Meyer’s Singleton </li></ul></ul>
  36. 40. References: Papers <ul><li>Object Lifetime Manager – A Complementary Pattern for Controlling Object Creation and Destruction by David L. Levine and Christopher D. Gill Douglas C. Schmidt , Design Patterns in Communications , (Linda Rising, ed.), Cambridge University Press, 2000. </li></ul>
  37. 41. Credits / Acknowledgements <ul><li>Debabrata Singha, ATOS Origin </li></ul><ul><ul><li>discussion on the “Object Lifetime Manager” paper. </li></ul></ul><ul><ul><li>understanding the atexit() behavior </li></ul></ul>
  38. 42. Thank You

×