多线程中如何安全的使用std::cout

问题描述

在C++多线程编程中,开发者往往使用cout来打印一些信息,但是往往被人忽略的是,cout在使用时可能会存在线程之间的打印信息乱串的问题,这个问题的分析原因可以参考:https://stackoverflow.com/questions/14718124/how-to-easily-make-stdcout-thread-safe,简而言之,是因为当开发者使用cout打印时,往往都会采用“<<”操作符,如:

std::cout << "This is " << name << ",id = " << id << std::endl;

而"<<"这个操作符是线程不安全的,会造成竞争问题。
下面是两个线程打印的例子,可以观察到打印乱串的现象:

#include <iostream>
#include <thread>
#include <stdio.h>

void PrintFunc(std::string name, std::string country)
{
    while (true) {
        std::cout << "I am " << name << ", from " << country << std::endl;
    }
}

int main()
{
    auto t1 = std::thread(PrintFunc, "Tom", "USA");
    auto t2 = std::thread(PrintFunc, "Xiaopeng", "China");

    t1.join();
    t2.join();

    return 0;
}
image.png

解决方案

方案1

将std::cout用printf替换,如下:

printf("I am %s, from %s\n", name.c_str(), country.c_str());

方案2

避免使用operator <<,在打印信息之前,先生成一个打印字符串,如下:

std::string msg = "";
msg = msg + "I am" + name + ", from " + country + "\n";
std::cout << msg;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容