Thread: making a class only get constructed once

  1. #31
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Bubba View Post
    Case in point. What happens in this section of code if two threads pass the if conditional?
    That is multi-threaded issues, and these issues affects everything you make, so it's hardly fair to say that it's a design flaw for this specific piece of code. It wasn't made to be thread safe. Can it be done? Sure. But at a cost. If you don't need it to be thread-safe, or if you want the caller to make it thread-safe, then why implement such a protection at all when all it does is add overhead?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #32
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by medievalelks View Post
    A single instance of a non-singleton still has to have its creation managed somewhere in the program, and is subject to the same synchronization issues in a MT environment, no?
    Of course all data access from different threads
    must be serialized properly to avoid races. In many cases the designer can hide the thread safety code from the client. And if still something goes wrong: nearly every programmer will know how to help you securing your data access (much fewer know how to compute data in parallel using techniques which scale, but that doesn't count here)

    But the issue with singleton instantiation is worse:

    Code:
    class C :public Singleton{};
    ...
    void f1() {
    C::instance(); }
    ...
    void f2() {
    C::instance(); }
    How many objects do you have if this is a single threaded program? One.
    How many objects does your mate who re-uses your object produce in his multithreaded multi-module program? You as the class designer can't know. If he doesn't know about the singleton problems he probably thinks one, because the code worked inside your program for years.
    But some access to his singleton objects doesn't seem to go right although he secured every data access...
    Now post this vague problem to a forum and better prepare some cans of coffee for the next few nights of code review...

    Quote Originally Posted by medievalelks View Post
    Cannot the same problem occur (more easily perhaps) with a single object passed by reference? What's to stop a programmer from constructing one where he thinks he needs it?
    Unfortunately nothing.
    The singleton problems are not about programmers doing something wrong. Rather it is about things which looks right but break during the costumer demo.
    Last edited by pheres; 04-14-2009 at 11:01 AM.

  3. #33
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by pheres View Post

    Code:
    class C :public Singleton{};
    ...
    void f1() {
    C::instance(); }
    ...
    void f2() {
    C::instance(); }
    How many objects do you have if this is a single threaded program? One.
    How many objects does your mate who re-uses your object produce in his multithreaded multi-module program? You as the class designer can't know.
    How is any of that mitigated with a class that you intend, but don't enforce, to have only one instance?

  4. #34
    The larch
    Join Date
    May 2006
    Posts
    3,573
    For one thing this lazy instantiation is a bit of a problem. If you create a single instance normally or through Elysia's factory before other threads start, you won't have this problem.

    Using the singleton in multiple threads might be quite problematic though.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #35
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by medievalelks View Post
    How is any of that mitigated with a class that you intend, but don't enforce, to have only one instance?
    You can't enforce singularity (if you consider re-usability - At least I don't know a method which is guaranteed to work under all circumstances. And if you search the net you will see I'm not alone). So what is left?
    -Method a (singleton) which promises things it can't hold
    -Method b - the standard method everybody knows to use

    What of both would you put into your companies code base?
    Last edited by pheres; 04-14-2009 at 11:38 AM.

  6. #36
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I think that it also tends to be more difficult to design unit tests involving singletons.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #37
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Seems like thread-safety could be enforced by a simple spinlock during object construction.

    Code:
    void SpinLock(int &lock);
    void SpinUnlock(int &lock);
    
    class TheSingleton
    {
        static int mSpinLock;
        static bool mInstantiated;
    
    public:
        static void DoInstantiate();
    
        static void Instantiate()
        {
            SpinLock(mSpinLock);
            if(!mInstantiated)
            {
                DoInstantiate();
                mInstantiated = true;
            }
            SpinUnlock(mSpinLock);
    };
    
    int TheSingleton::mSpinLock = 0;
    bool TheSingleton::mInstantiated = false;
    Sure, if two threads try to instantiate at the same time, one of them will spin for a while -- but it will only happen once, and ONLY if two threads try to instantiate at the same time.

    There are no blocking waits, no OS dependencies.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #38
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    The multithreading problem is easy to solve using pthread_once or similar. But what will happen if someone calls Instantiate() from a shared lib/dll/whatever_your_OS supports? This imo depends on the behavior of the OS.

  9. #39
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by pheres View Post
    The multithreading problem is easy to solve using pthread_once or similar. But what will happen if someone calls Instantiate() from a shared lib/dll/whatever_your_OS supports? This imo depends on the behavior of the OS.
    The same thing that will happen if they invoke the constructor on your non-Singleton solution.

  10. #40
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    No, because they have no static flags which marks instantiated or not. These flags will either reside on a single one or more memory locations, depending on your OS. Try it out. Linux and WinXp should be enough to find a difference.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Creating a database
    By Shamino in forum Game Programming
    Replies: 19
    Last Post: 06-10-2007, 01:09 PM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM