#include <iostream>
#include <unordered_map>
#include <vector>
#include <thread>
#include <algorithm>
#include <mutex>
using namespace std;
class single
{
public:
// Every thread needs to call this to get its individual instance
static single* getInstance( unsigned int threadId );
static void print( unsigned int threadId )
{
std::cout << "threadId:" << threadId << ", Singleton: " << _instances[threadId] << std::endl;
}
protected:
// Made protected not private so that singleton can be subclassed
single(); // Clients cant construct objects directly
~single(); // cannot be destroyed by clients
single(const single &) = delete; // non-copyable
single& operator=(const single &) = delete; // can't be copy assigned
single(single &&) = delete; // non-move constructible
single & operator=(single && ) = delete; // non-move assignable
private:
static std::unordered_map<unsigned,single*> _instances;
static std::mutex _lock;
};
std::mutex single::_lock;
std::unordered_map<unsigned,single*> single::_instances;
single::single(){}
single::~single(){}
single* single::getInstance( unsigned int threadId )
{
if( _instances.count( threadId ) == 0 )
{
std::lock_guard<std::mutex> lg(_lock);
if( _instances.count( threadId ) == 0 )
{
_instances[threadId] = new single;
std::cout <<"Created By ThreadId: " << threadId <<std::endl;
}
}
return _instances[threadId];
}
void Run( unsigned int threadId )
{
single::getInstance(threadId)->print(threadId);
}
int main()
{
std::vector<std::thread> workers;
const unsigned threadCount = 16;
for( auto i = 0; i != threadCount; ++i )
{
workers.push_back( std::thread( Run, i ) );
}
for_each( workers.begin(), workers.end(), std::mem_fn(&thread::join) );
return 0;
}