1 线程安全std::cout

最近在多个子线程中使用std::cout输出日志信息发现std::cout不是线程安全的,无法保持线程同步,导致日志信息无法按照固定顺序输出,现象如下:

C++ – 线程安全的std::cout-StubbornHuang Blog

所以对std::cout做了一个封装以保证多线程之间的同步,代码如下:

#include <iostream>
#include <string>

#include <mutex>

namespace ThreadSafePrint
{
    static std::mutex m_CoutMutex;
    struct cout
    {
        std::unique_lock<std::mutex> m_Lock;
        cout():
            m_Lock(std::unique_lock<std::mutex>(m_CoutMutex))
        {

        }

        template<typename T>
        cout& operator<<(const T& message)
        {
            std::cout << message;
            return *this;
        }

        cout& operator<<(std::ostream& (*fp)(std::ostream&))
        {
            std::cout << fp;
            return *this;
        }
    };
}

调用示例:

ThreadSafePrint::cout() << "Hello World" << std::endl;

测试程序如下:

#include <iostream>
#include <string>

#include <mutex>
#include <thread>

namespace ThreadSafePrint
{
    static std::mutex m_CoutMutex;
    struct cout
    {
        std::unique_lock<std::mutex> m_Lock;
        cout():
            m_Lock(std::unique_lock<std::mutex>(m_CoutMutex))
        {

        }

        template<typename T>
        cout& operator<<(const T& message)
        {
            std::cout << message;
            return *this;
        }

        cout& operator<<(std::ostream& (*fp)(std::ostream&))
        {
            std::cout << fp;
            return *this;
        }
    };
}



void Thread1()
{
    for (int i=0;i<10000;++i)
    {
        ThreadSafePrint::cout() <<std::this_thread::get_id() <<" : aa" << std::endl;
        //std::cout << std::this_thread::get_id() << " : aa" << std::endl;
    }
}

void Thread2()
{
    for (int i = 0; i < 10000; ++i)
    {
        ThreadSafePrint::cout() << std::this_thread::get_id() << " : bb" << std::endl;
        //std::cout << std::this_thread::get_id() << " : bb" << std::endl;
    }   
}

void Thread3()
{
    for (int i = 0; i < 10000; ++i)
    {
        ThreadSafePrint::cout() << std::this_thread::get_id() << " : cc" << std::endl;
        //std::cout << std::this_thread::get_id() << " : cc" << std::endl;
    }
}

int main()
{
    std::thread printThread1(Thread1);
    std::thread printThread2(Thread2);
    std::thread printThread3(Thread3);

    printThread1.join();
    printThread2.join();
    printThread3.join();

    getchar();
    return 0;
}