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

C++ multithread program I/O problem with std::endl

本文关键字:程序 问题 多线程 std endl C++      更新时间:2023-10-16

我尝试学习如何使用 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"消失了。你能帮我弄清楚吗?非常感谢!

您有 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;
    }

我想我也应该收到三个''吧?

有问题的三个'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;
  • 等。