【问题记录】多线程环境下,使用 std::cout 输出内容会显示混乱

  • Windows 11 家庭中文版
  • Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.5.3

#include 
#include 

//创建的线程数量
#define THREAD_COUNT    4

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    UNREFERENCED_PARAMETER(lpParam);    //未使用参数

    std::cout << "Thread " << GetCurrentThreadId() << ": succeeded" << std::endl;
    //printf("Thread %d: executed\n",GetCurrentThreadId());
    Sleep(5);   //模拟线程在任务上花费的时间

    return true;
}

int main()
{
    HANDLE m_thread[THREAD_COUNT] = {nullptr};
    DWORD m_threadID;

    //创建工作线程
    for (int i = 0; i < THREAD_COUNT; i++) {
        m_thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, &m_threadID);

        std::cout << "Working thread:" << m_threadID << std::endl;
        //printf("Working thread %d\n", m_threadID);

        if (m_thread[i] == NULL) {
            std::cout << "CreateThread error:" << GetLastError() << std::endl;
            //printf("CreateThread error: %d\n", GetLastError());
            return i;
        }
    }

    //关闭线程
    for (int i = 0; i < THREAD_COUNT; i++) {
        CloseHandle(m_thread[i]);
    }
    return 0;
}

  1. 输出内容如下所示,并且每次运行的输出效果都会不一样,这就可能是因为 std::cout 不是线程安全的,无法保持线程同步,所以导致输出内容到窗口会混乱。【问题记录】多线程环境下,使用 std::cout 输出内容会显示混乱_第1张图片

  1. 将上述测试代码中的 std::cout 语句注释掉,用 printf 语句打印内容。(这时内容打印正常)【问题记录】多线程环境下,使用 std::cout 输出内容会显示混乱_第2张图片
  2. 对于 std::cout 线程不安全问题,目前的想法就是对 std::cout 进行线程安全的封装,并使用互斥锁进行同步操作。
    #include 
    #include 
    
    class ThreadSafeCout
    {
    public:
        template 
        ThreadSafeCout& operator<<(const T& value)
        {
            std::lock_guard lock(m_mutex);
            std::cout << value;
            return *this;
        }
    
        // 处理特殊情况:std::endl
        ThreadSafeCout& operator<<(std::ostream& (*pf)(std::ostream&))
        {
            std::lock_guard lock(m_mutex);
            std::cout << pf;
            return *this;
        }
    
    private:
        //声明为静态成员变量,可以让所有的 ThreadSafeCout 对象将共享相同的互斥锁
        static std::mutex m_mutex;
    };
    // 静态成员的初始化
    std::mutex ThreadSafeCout::m_mutex;

你可能感兴趣的:(问题记录,ide,c++)