C ++多线程程序I / O问题与std :: endl

时间:2019-01-10 07:59:14

标签: c++ multithreading io

我尝试学习如何使用C ++ 11线程库,然后,我对以下代码的输出感到困惑。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void thread_function()
{
    std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;
}

int main()
{
    std::thread threadObj1(thread_function);
    std::thread threadObj2(thread_function);

    if (threadObj1.get_id() != threadObj2.get_id())
        std::cout << "Both threads have different id" << std::endl;

    threadObj1.join();
    threadObj2.join();
    std::cout<<"From Main Thread :: ID of Thread 1 = "<<threadObj1.get_id()<<std::endl;
    std::cout<<"From Main Thread :: ID of Thread 2 = "<<threadObj2.get_id()<<std::endl;


    return 0;
}

我将每个std :: cout附加到std :: endl以便刷新缓冲区并输出'/ n'字符。但是,最终我得到了如下输出。

Both threads have different idInside Thread :: ID = Inside Thread :: ID = 
0x700003715000
0x700003692000
From Main Thread :: ID of Thread 1 = 0x0
From Main Thread :: ID of Thread 2 = 0x0
Program ended with exit code: 0

内部线程之前的'/ n'似乎消失了。你能帮我弄清楚吗?非常感谢!

2 个答案:

答案 0 :(得分:2)

您有3个线程正在访问cout,而没有任何同步。您已定义mtx,但未使用它,为什么?

添加lock_guard来保护cout语句:

void thread_function()
{
    std::lock_guard<std::mutex> lk{mtx};
    std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;
}

    if (threadObj1.get_id() != threadObj2.get_id())
    {
        std::lock_guard<std::mutex> lk{mtx};
        std::cout << "Both threads have different id" << std::endl;
    }

答案 1 :(得分:1)

  

我想我也应该收到三个'\ n'对吗?

有问题的三个'\n'字符在您的输出中。在输出的前三行的结尾。

我认为您可能误解了示例中的这一行是什么意思

std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;

在这一行代码中有四个单独的函数调用。那一行与这四行完全相同:

std::cout << "Inside Thread :: ID = ";
auto id = std::this_thread::get_id();
std::cout << id;
std::cout << std::endl;

即使假设std::cout对象是完全同步的,您也没有采取任何措施来防止各种线程交错单独的函数调用。例如,

  • 主线程调用std::cout << "Both threads have different id";
  • threadObj1调用std::cout << "Inside Thread :: ID = ";
  • threadObj2调用std::cout << "Inside Thread :: ID = ";
  • 主线程调用std::cout << std::endl;
  • threadObj1调用std::cout << std::this_thread::get_id();
  • threadObj1调用stc::cout << std::endl;