#include <mutex>
#include <thread>
#include <sstream>
#include <iostream>
#include <vector>


std::once_flag g_flag;

class Singleton
{
private:
    Singleton(){}
    static void CreateInstance()
    {
        pToSelf = new Singleton();
        static ToDestroy destroy;
    }

public:
    static Singleton* getInstance()
    {
        std::call_once(g_flag, CreateInstance);
        return pToSelf;
    }

private:
    static Singleton* pToSelf;

    class ToDestroy
    {
    public:
        ~ToDestroy()
        {
            if(Singleton::pToSelf)
            {
                delete Singleton::pToSelf;
                pToSelf = nullptr;
                std::cout << "~ToDestroy() call \n";
            }
        }
    };
};

Singleton* Singleton::pToSelf = nullptr;



struct pcout: public std::stringstream
{
    ~pcout()
    {
        std::lock_guard<std::mutex> lk(pMutex);
        std::cout << rdbuf();
        std::cout.flush();
    }
private:
    static std::mutex pMutex;
};

std::mutex pcout::pMutex;

void func()
{

    Singleton *p = Singleton::getInstance();

    // cout 非线程安全   printf是线程安全
    // std::cout << "thread id : " << std::this_thread::get_id() << ' ' << (p) << std::endl;

    pcout{} << "thread id : " << std::this_thread::get_id() << ' ' << (p) << std::endl;
}

int main(void)
{
    std::vector<std::thread> threads;

    for(size_t i = 0; i<10; ++i)
    {
        threads.emplace_back(func);
    }

    for(auto &it : threads)
        it.join();

    return 0;
}
02-10 02:07