【C++】std::osyncstream

std::osyncstream 是 C++20 中引入的一个同步输出流包装器,用于解决多线程中标准输出因没有同步而导致输出乱序的问题。它确保每次输出操作都是原子的,即使在多线程环境中也不会出现乱序或重叠。

1. 背景

std::cout在执行过程中也会被打断,不是原子操作。
在多线程程序中,多个线程可能同时向标准输出(如 std::cout)写入内容。如果没有同步机制,输出可能会出现乱序或重叠的情况。例如:

//因t1和t2没有同步机制,两个线程在执行std::cout时可能发生线程切换,导致最后看到的t1,t2的输出结果是交叉在一起。
#include <iostream>
#include <thread>

void print_from_thread(int id) {
    std::cout << "Thread " << id << " is printing this line." << std::endl;
}

int main() {
    std::thread t1(print_from_thread, 1);
    std::thread t2(print_from_thread, 2);
    t1.join();
    t2.join();
    return 0;
}

2. std::osyncstream

  • #include <syncstream>
  • std::osyncstream 是 C++20 中引入的一个同步输出流包装器,用于解决上述问题。它确保每次输出操作都是原子的,即使在多线程环境中也不会出现乱序或重叠。
  • std::osyncstream 包装了一个底层输出流(如 std::cout),并提供同步机制。
  • std::osyncstream 的同步机制决定了你必须显式地 flush 或者让其析构才能把内容真正送到 std::cout;否则缓冲区里的数据会一直留在 osyncstream 对象里,程序结束前不会输出。
  • std::osyncstream 内部使用互斥锁(mutex)来同步对底层输出流的访问。每次调用 std::osyncstream 的输出操作时,它会锁定互斥锁,完成输出后再释放锁,从而确保输出的原子性
  • std::osyncstream 是 C++20 标准的一部分,因此需要使用支持 C++20 的编译器,并启用 C++20 标准(如:-std=c++20,vs中要在项目属性中设置C++标准为C++20)。
  • 使用 std::osyncstream 会引入一定的性能开销,因为每次输出都需要获取和释放互斥锁。
#include <iostream>
#include <thread>
#include <syncstream> // 包含 std::osyncstream 的头文件

void print_from_thread(int id) {
    std::osyncstream(std::cout) << "Thread " << id << " is printing this line." << std::endl;
}

int main() {
    std::thread t1(print_from_thread, 1);
    std::thread t2(print_from_thread, 2);
    t1.join();
    t2.join();
    return 0;
}
posted @ 2025-07-23 09:37  仰望星河Leon  阅读(34)  评论(0)    收藏  举报