Skip to main content
gamedev.net
🔒 Locked

Singleton implementation questions.

Started by ManaStone Sep 18, 2005 at 6:19 PM 11 replies 950+ views
Original Post
ManaStone
ManaStone
Ok first off. I’ve read in a tutorial that in single threaded applications doing something like:

Singleton* getInstance()
{
	static Singleton Instance;
	
	return &Instance.

}



is alright, but once you do it in multithreaded applications it becomes a problem because of the way static memory is allocated. So, in multithreaded applications we need to do something like this:

class Singleton{
	static Singleton *pInstance;
	Singleton *getInstance()
	{
		if(pInstance==NULL)
		pInstance= new Singleton;

		return pInstance;
	}

};
Singleton *Singleton::pInstance=NULL;



My first question: In a multithreaded application, how come we can use static member variables, but we cannot use static variables when it is declared inside a function. My second question: How do I not get linker errors when I use the statement

Singleton *Singleton::pInstance=NULL;
 


right outside of the class? Let me clarify: I use the format where I put everything in my main header like so

#ifndef _MY_MAIN_
#define _MY_MAIN_


#include <iostream.h>
#include <windows.h>
#include <gl\Gl.h>  
#include "Singleton.h"
#include "cSmtPtr.h"

#endif 



and then each of my cpp files has the “main.h” header in it. I get linker errors because “class Singleton * Singleton::pInstance" has already been defined in another object. Does anyone have a solution for me? [Edited by - ManaStone on September 18, 2005 6:39:25 PM]
-----------------------------Download my real time 3D RPG.
SiCrane
SiCrane
Quote:
Original post by ManaStone
My first question: In a multithreaded application, how come we can use static member variables, but we cannot use static variables when it is declared inside a function.

In multithreaded applications you actually can't use either safely from multiple threads without some sort of protection.


I'm not sure I understand your second question.

brulle
brulle
You must define the pointer in one place only. Preferably in a .cpp file. So move it out of the .h file where you declare the class to the file where you define the rest of the class (i presume you don't only have inline functions).
ManaStone
ManaStone
My second question is how do I avoid linker errors when initializing the pInstance outside the class.

Also, do you know of a link to an article that allows me to safely implement singleton classes?
-----------------------------Download my real time 3D RPG.
ManaStone
ManaStone
Quote:
Original post by brulle
You must define the pointer in one place only. Preferably in a .cpp file. So move it out of the .h file where you declare the class to the file where you define the rest of the class (i presume you don't only have inline functions).


Alright thanks. I don't know why I didn't think of that. For some reason I wanted to solve the problem using the extern key word.
-----------------------------Download my real time 3D RPG.
brulle
brulle
By the way your first example is erroneous. You should return a reference or a pointer.
ManaStone
ManaStone
Quote:
Original post by brulle
By the way your first example is erroneous. You should return a reference or a pointer.


I know, I was just hacking out some quick code.
-----------------------------Download my real time 3D RPG.
hplus0603
hplus0603
The compiler will internally generate the second version of the code for the code you have in the first version, so they are equivalent (apart from the call to "new" as opposed to static memory). Neither is safe for threaded use.

To support threaded use, you have to either acquire some form of lock each time through the accessor, which would be fairly expensive, or you have to map the accessor to thread-local storage, so that each thread gets its own instance of the singleton. However, clean-up when a thread exists may be a problem with thread-locals.
enum Bool { True, False, FileNotFound };
brulle
brulle
Quote:
Original post by ManaStone
I don't know why I didn't think of that. For some reason I wanted to solve the problem using the extern key word.


Yes i have had that idea too in the past. I think you do that sometimes with globals in c?
ManaStone
ManaStone
Quote:
Original post by hplus0603
The compiler will internally generate the second version of the code for the code you have in the first version, so they are equivalent (apart from the call to "new" as opposed to static memory). Neither is safe for threaded use.

To support threaded use, you have to either acquire some form of lock each time through the accessor, which would be fairly expensive, or you have to map the accessor to thread-local storage, so that each thread gets its own instance of the singleton. However, clean-up when a thread exists may be a problem with thread-locals.


So what if I'm not really doing any coding that involves multithreading, but I have to set up the compiler so it uses a multithreaded runtime library? Does that make my application automatically multithreaded? I have to set it this way in order to use SDL.
-----------------------------Download my real time 3D RPG.
brulle
brulle
Quote:
Original post by ManaStone
So what if I'm not really doing any coding that involves multithreading, but I have to set up the compiler so it uses a multithreaded runtime library? Does that make my application automatically multithreaded? I have to set it this way in order to use SDL.


This should not affect your own code, since SDL itself is not accessing any of your classes. So as long as the class is used in one thread only you needn't worry bout any multithread issues.
brulle
brulle
I'd like to add that if a class doesn't have static members then I am pretty sure you can, if you are inclined to, use separate instances in separate threads too without any issues.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.