C++20stladvanced
std::syncbuf / std::osyncstream (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Synchronized output stream wrappers that buffer output and flush atomically, preventing interleaved output from multiple threads. `syncbuf` is the buffer; `osyncstream` is the stream wrapper.
Real-World Scenario
Log diagnostic messages from multiple worker threads to stdout without garbled interleaving.
Quick Snippet
snippet.cpp
#include <syncstream>
#include <iostream>
#include <thread>
void worker(int id) {
std::osyncstream(std::cout) << "Worker " << id << " started\n";
// Entire line is flushed atomically
}Full Example
syncstream.cpp
// CodeNebula - C++20 Example: std::syncbuf and std::osyncstream
// Compile: g++ -std=c++20 -Wall -Wextra -pthread -o example syncstream.cpp
#include <iostream>
#include <syncstream>
#include <thread>
#include <vector>
#include <string>
void print_unsync(int id) {
std::cout << "Thread " << id << ": unsynchronized line 1\n";
std::cout << "Thread " << id << ": unsynchronized line 2\n";
}
void print_sync(int id) {
// osyncstream buffers the entire output and flushes atomically
std::osyncstream out(std::cout);
out << "Thread " << id << ": Hello from synchronized output!\n";
out << "Thread " << id << ": This will NOT interleave.\n";
// Flushed atomically when 'out' is destroyed
}
int main() {
const int num_threads = 4;
// Demonstrate unsynchronized output (may interleave)
std::cout << "=== Unsynchronized output ===\n";
{
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i)
threads.emplace_back(print_unsync, i);
for (auto& t : threads) t.join();
}
std::cout << "\n=== Synchronized output ===\n";
{
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i)
threads.emplace_back(print_sync, i);
for (auto& t : threads) t.join();
}
// Using osyncstream for formatted multi-line atomic output
std::cout << "\n=== Formatted synchronized output ===\n";
{
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back([i] {
std::osyncstream sync_out(std::cout);
sync_out << "--- Worker " << i << " Report ---\n";
sync_out << " Status: running\n";
sync_out << " Items processed: " << (i + 1) * 10 << "\n";
sync_out << "--- End Worker " << i << " ---\n";
});
}
for (auto& t : threads) t.join();
}
// Manual emit for explicit flush control
std::cout << "\n=== Manual emit ===\n";
{
std::osyncstream sync_out(std::cout);
sync_out << "First part... ";
sync_out.emit(); // flush now
sync_out << "Second part.\n";
// remainder flushed on destruction
}
return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -pthread -o example syncstream.cpp