I would like to create a singleton class that is instantiated once in each thread where it is used. I would like to store the instance pointers in TLS slots. I have come up with the following solution but I am not sure whether there are any special considerations with multithreaded access to the singelton factory when thread local storage is involved. Maybe there is also a better solution to implement thread local singletons.
class ThreadLocalSingleton
{
static DWORD tlsIndex;
public:
static ThreadLocalSingleton *getInstance()
{
ThreadLocalSingleton *instance =
static_cast<ThreadLocalSingleton*>(TlsGetValue(tlsIndex));
if (!instance) {
instance = new ThreadLocalSingleton();
TlsSetValue(tlsIndex, instance);
}
return instance;
}
};
DWORD ThreadLocalSingleton::tlsIndex = TlsAlloc();
The Tls*-functions are of course win32 specific but portability is not the main issue here. Your thoughts concerning other platforms would still be valuable.
Major Edit: I had originally asked about using double-checked locking in this scenario. However as DavidK pointed out, the singletons are to be created on a per thread basis anyway.
The two remaining questions are:
is it appropriate to reply on TlsGetValue/TlsSetValue to ensure that each thread gets one instance and that the instance is created only once for each thread?
Is it possible to register a callback that allows me to clean up an instance that was associated with a particular thread when that thread finishes?
Since your objects are thread-local, why do you need locking to protect them at all? Each threads that calls getInstance() will be independent of any other thread, so why not just check that the singleton exists and create it if needed? The locking would only be needed if multiple threads tried to access the same singleton, which isn't possible in your design as it is above.
EDIT: Moving on to the two other questions... I can't see any reason why using TlsAlloc/TlsGetValue etc. wouldn't work as you'd expect. Since the memory holding the pointer to your singleton is only accessible to the relevant thread, there won't be any problems with a lazy initialization of it. However there's no explicit callback interface to clean them up.
The obvious solution to that would be to have a method that is called by all your thread main functions that clears up the created singleton, if any.
If it's very likely that the thread will create a singelton, a simpler pattern might be to create the singleton at the start of the thread main function and delete it at the end. You could then use RAII by either creating the singleton on the stack, or holding it in a std::auto_ptr<>, so that it gets deleted when the thread ends. (Unless the thread terminates abnormally, but if that happens all bets are off and a leaked object is the least of your problems.) You could then just pass the singleton around, or store it in TLS, or store it in a member of a class, if most of the thread functionality is in one class.
Have a look at this paper to understand why double-checked locking doesn't work in general (even though it might work in special cases).
We use a class that stores a map of thread id to data to implement our thread local storage. This seems to work very well, then an instance of this class can be placed anywhere you require thread local storage. Normally clients use an instance of as a static private field.
Here is a rough outline of the code
template <class T>
struct ThreadLocal {
T & value()
{
LockGuard<CriticalSection> lock(m_cs);
std::map<int, T>::iterator itr = m_threadMap.find(Thread::getThreadID());
if(itr != m_threadMap.end())
return itr->second;
return m_threadMap.insert(
std::map<int, T>::value_type(BWThread::getThreadID(), T()))
.first->second;
}
CriticalSection m_cs;
std::map<int, T> m_threadMap;
};
This is then used as
class A {
// ...
void doStuff();
private:
static ThreadLocal<Foo> threadLocalFoo;
};
ThreadLocal<Foo> A::threadLocalFoo;
void A::doStuff() {
// ...
threadLocalFoo.value().bar();
// ...
}
This is simple and works on any platform where you can get the thread id. Note the Critical Section is only used to return/create the reference, once you have the reference all calls are outside the critical section.
Related
I have a table store a key value like data, which will be frequently used but rarely update. So I would like to store necessary data in the memory, and only update it when the update coming.
Here is the simple code show my current solution.
kv.h
class kv
{
public:
string query(string key);
void update(string key, string value);
};
kv.cpp
#include "kv.h"
#include <map>
#include <mutex>
#include <thread>
static map<string, string> s_cacheMap;
static mutex mtx;
string kv::query(string key)
{
unique_lock<mutex> lock(mtx);
if (s_cacheMap.empty())
{
// load from db
}
auto it = s_cacheMap.find(key);
if (it != s_cacheMap.end())
{
return (*it).second;
}
return "";
};
void kv::update(string key, string value)
{
unique_lock<mutex> lock(mtx);
s_cacheMap.clear();
// write key value into db
};
Problem of this solution
Those code will be part of the library in the iOS platform wrote by C++. The app might be killed by system or user at anytime. I could get notification when app exit, but I only have a very short time to clean up before user terminate the app. I couldn't guarantee those threads still running when application is terminating get correct result, but I'd like to make sure it doesn't crash.
At the end of the application lifecycle, those two static variable will be destroyed. When those two static variable have been destroyed, another thread try to call those two method, it will fail.
Possible solutions
1 - Wrap the static into a method like that
map<string, string>& getCacheMap()
{
static map<string, string> *s_cacheMap = new map<string, string>;
return *s_cacheMap;
}
2 - Make kv class as singleton
static kv& getInstance()
{
static kv* s_kv = new kv();
return *s_kv;
}
Problem
Beside those two solutions, is there any other possible solution for that kind of problem?
When those two static variable have been destroyed, another thread try
to call those two method, it will fail.
Your real problem here is that you still have threads running at the end of main(). That's no good; even if you work around this particular problem, you will continue to get bit by other (similar) race conditions on shutdown, some of which you won't be able to work around.
The proper fix is to make sure that all spawned threads have exited and are guaranteed to be gone before you do any cleanup of resources they might access (e.g. before main() returns, in this case). In particular, you need to tell each thread to exit (e.g. by setting a std::atomic<bool> or similar that the thread checks periodically, or closing a socket that the thread is monitoring, or by any other cross-thread notification mechanism you can come up with), and then have the main thread call join() on the thread object so that the main thread will block inside join() until the child thread has exited.
Once you've done that, there will be no more race conditions during shutdown, because there will be no threads left to inappropriately try to access the resources that are being deleted.
Use indirection - the solution to all programming problems.
Create an interface class to your data structure - in this case two methods, query and update - where all methods are pure virtual.
Declare the static to be a pointer to this interface type.
Create two implementation subclasses: one is the real one, the other does nothing (but return default values where necessary).
At app start time create a real instance, stick it in the static pointer. At app exit time, create a do-nothing instance, swap it into the static pointer, and delete the real instance that was in the static pointer. (Or don't delete it if the app/process is actually going away.)
Since this map is being updated it obviously already has a global lock (or read-write lock). The swap-pointer operation needs to take that lock too, to make sure nobody is in the data structure while you swap it. But the lock needs to moved to the pointer from the data structure. Easiest way to do that is to have a third subclass of the interface which holds a pointer to the data structure (the previous 'static pointer') and forwards all operations to the contained instance after taking the proper lock.
(This sounds complex, but it isn't really, and I've done it myself in a situation where we had to load a DLL into an OS network stack, where it would stay without being able to be unloaded until the OS was rebooted, but where the implementation of the DLL needed to be upgraded when the app was upgraded, the time of which happened independently of needing to reboot the OS. I provided an entire forwarding DLL which could be loaded into the OS, and it loaded/unloaded/reloaded the actual DLL that did the work, forwarding all operations to it, and tracking when the older DLL was no longer used (all operations returned) and could be freed.)
Alternative, unnecessary except for the truely paranoid: The do-nothing instance could be declared static too, then you just put a pointer to it into the static pointer-to-interface at app exit. It doesn't need to be cleaned up (deleted).
You know, if this is an application lifecycle thing, and the process is getting destroyed anyway, why not just not clean up this static map at all?
I have seen code where mutex or critical section is declared as member variable of the class to make it thread safe something like the following.
class ThreadSafeClass
{
public:
ThreadSafeClass() { x = new int; }
~ThreadSafeClass() {};
void reallocate()
{
std::lock_guard<std::mutex> lock(m);
delete x;
x = new int;
}
int * x;
std::mutex m;
};
But doesn't that make it thread safe only if the same object was being shared by multiple threads? In other words, if each thread was creating its own instance of this class, they will be very much independent and its member variables will never conflict with each other and synchronization will not even be needed in that case!?
It appears to me that defining the mutex as member variable really reduces synchronization to the events when the same object is being shared by multiple threads. It doesn't really make the class any thread safer if each thread has its own copy of the class (for example if the class were to access other global objects). Is this a correct assessment?
If you can guarantee that any given object will only be accessed by one thread then a mutex is an unnecessary expense. It however must be well documented on the class's contract to prevent misuse.
PS: new and delete have their own synchronization mechanisms, so even without a lock they will create contention.
EDIT: The more you keep threads independent from each other the better (because it eliminates the need for locks). However, if your class will work heavily with a shared resource (e.g. database, file, socket, memory, etc ...) then having a per-thread instance is of little advantage so you might as well share an object between threads. Real independence is achieved by having different threads work with separate memory locations or resources.
If you will have potentially long waits on your locks, then it might be a good idea to have a single instance running in its own thread and take "jobs" from a synchronized queue.
I want to create a thread safe singleton class.
The current way to achieve the same(that I know of) is by having a static method in the class which returns the static object as below:
Singleton & Singleton::getInstance()
{
static Singleton instance;
return instance;
}
The problem with having this approach is that since the created object is static, its cleanup happens at application exit. Ideally I would like to have control over when the destruction exactly happens.
I did some digging and found that I can use the static ptr to instance way and have a separate cleanup function, but to make it thread safe I will have to use double check locking with explicit memory barriers.
Is there a simpler to comprehend(I am not an expert) way to achieve the same?
I did find plenty of questions regarding singletons and thread safety, but none that quite answered this question for me... but I apologize if it is a repeat.
If I have a singleton object which will be used by multiple threads, I understand that any mutation to member variables should be carefully considered, but what about variables that are local to a method?
Consider this psuedo-code:
class Singleton [assume this has all the trappings of a proper singleton]
{
int doSomething() {
SomeObject obj;
obj.doStuff();
return obj.result();
}
}
In this case, is the local 'obj' thread safe? Does each thread get its own copy of it, even though there is only one object of the Singleton class?
Yes, obj is unique per thread.
There could be threading issues however if it accessed & modified common data - for example doStuff or result accesses a static member of SomeObject or some global.
As Luchian said you are fine so far, however, if you have a static or any & or * variable, then try to use a mutex lock or a spin lock. Mutex locks and spin locks exist in all unix based systems, and I think you can use them in windows as well, but you need first to add them somehow.
Here is a link for pthread mutexes: http://www.thegeekstuff.com/2012/05/c-mutex-examples/
And here another one for windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927(v=vs.85).aspx
What is a good way to implement a singleton that will be restricted only to the thread that seeks its instance? Is there a thread id or something that I can use to do that? I'm using Carbon threading API but will have to implement this on windows and pure POSIX later too, so any technique is appreciated.
How about something similar to ThreadLocal in Java? Posix/Carbon should have something ThreadLocal right?
In the past, I have leveraged a hashmap or index to store data structures that are per-thread inside of a single global thread-safe data structure. For instance, if you provide the id for each thread as an incrementing integer, you can store your data structure in a pre-allocated array at the index of the thread it. If you are leveraging thread IDs that are provided by the operating system or need to be more flexible, then a thread safe HashMap or HashTable will come in quite handy.
Jacob
I'd want to put the singleton pointer into whatever the system's thread local storage method is. You've named several, and I don't know the right incantations for them, but most threading systems have some kind of thread local storage concept.
If your threading system does not, AND your threading system does have a unique thread identifier, then a hash table (keyed by thread id) is probably your best bet.
We use a class that stores a map of thread id to data to implement our thread local storage. This seems to work very well, then an instance of this class can be placed anywhere you require thread local storage. Normally clients use an instance of as a static private field.
Here is a rough outline of the code
template <class T>
struct ThreadLocal {
T & value()
{
LockGuard<CriticalSection> lock(m_cs);
std::map<int, T>::iterator itr = m_threadMap.find(Thread::getThreadID());
if(itr != m_threadMap.end())
return itr->second;
return m_threadMap.insert(
std::map<int, T>::value_type(BWThread::getThreadID(), T()))
.first->second;
}
CriticalSection m_cs;
std::map<int, T> m_threadMap;
};
This is then used as
class A {
// ...
void doStuff();
private:
static ThreadLocal<Foo> threadLocalFoo;
};
ThreadLocal<Foo> A::threadLocalFoo;
void A::doStuff() {
// ...
threadLocalFoo.value().bar();
// ...
}
This is simple and works on any platform where you can get the thread id. Note the Critical Section is only used to return/create the reference, once you have the reference all calls are outside the critical section.
I'm not sure whether this will answer your question, but in my Design Pattern class, I've learned something like this:
- (id) getInstance{
#synchronized(self){
if (mySingletonInstance == nil){
#synchronized(self){
mySingletonInstance = [[mySingleton alloc] init];
}
}
}
return mySingletonInstance;
}
Although the code is in Objective-C, the idea should be about the same in other language, IMHO.
If you're happy with pthreads, you should be looking at
pthread_key_create
pthread_setspecific
pthread_getspecific
This should cover OSX and linux (I haven't used Carbon, but I'm guessing that it uses real OS threads and therefore plays nicely with pthreads).
Windows has the same basic idea with different names and a slightly different interface:
http://msdn.microsoft.com/en-us/library/ms686991.aspx
This allows you to access the "singleton"(*) for a thread only from that thread, but it sounds like that's what you want. If you want to be able to access any thread's object from any other thread, then you need a structure keyed on a pthread_t, and almost certainly some synchronisation. You get pthread_t values (that is, thread IDs) from pthread_self or pthread_create.
(*) If you have one per thread, it's technically not a singleton...