Synchronized buffered outputstream
Use case
Thread-safe logging without mixed output.
Explanation
std::osyncstream buffers output and flushes atomically. Without it, concurrent cout writes mix randomly. Note that it is not supported by Apple currently (look for “Synchronized buffered”).
Code
#include <cstdint>
#include <iostream>
#include <thread>
#include <vector>
#if defined(__APPLE__)
#include <mutex>
#define HAS_SYNCSTREAM 0
std::mutex cout_mutex;
#else
#include <syncstream>
#define HAS_SYNCSTREAM 1
#endif
void analyzeSegment(uint64_t addr, const char *name) {
#if HAS_SYNCSTREAM
std::osyncstream{std::cout} << "Thread " << std::this_thread::get_id()
<< ": analyzing " << name << " @ 0x" << std::hex
<< addr << "\n";
#else
std::lock_guard lock(cout_mutex);
std::cout << "Thread " << std::this_thread::get_id() << ": analyzing " << name
<< " @ 0x" << std::hex << addr << "\n";
#endif
}
int main() {
std::vector<std::jthread> threads;
threads.emplace_back(analyzeSegment, 0x10001000, "__TEXT");
threads.emplace_back(analyzeSegment, 0x10002000, "__DATA");
threads.emplace_back(analyzeSegment, 0x10003000, "__LINKEDIT");
return 0;
}
Output
$ ./src/c++20/build/synchronised-buffered-outputstream
Thread 139842723919552: analyzing __TEXT @ 0x10001000
Thread 139842715526848: analyzing __DATA @ 0x10002000
Thread 139842707134144: analyzing __LINKEDIT @ 0x10003000