用于将std::osyncstream和std::cout组合在一起的C++20自定义类
我想在多线程上下文中使用std::osyncstream和std::cout而不需要每次都写:
std::osyncstream(std::cout) << "my message" << std:endl;
我想要达到的目标:
streams::synced_cout << "my message" << std:endl;
我做了什么:
namespace streams {
class _synced_cout {
private:
std::osyncstream synced_cout_stream = std::osyncstream(std::cout);
public:
template <class T>
std::osyncstream &&operator<<(const T& value) {
synced_cout_stream << value;
return std::move(synced_cout_stream);
}
};
inline static _synced_cout synced_cout = _synced_cout();
}
但是什么都没有显示,我有什么想念的?或者是否存在更简单的解决方案?
回答
osyncstream有点像unique_lock:每个线程都需要构造自己的实例,osyncstream因为对osyncstream自身的访问没有同步。它所做的只是在内部缓冲区中缓冲输出,并最终将其传输到包装的流(或实际上,streambuf)。只有传输步骤是同步的。
osyncstream因此,拥有一个全局是完全没有意义的。如果从多个线程访问,那就是数据竞争;如果没有,osyncstream首先使用没有意义。
传输缓冲输出
- 当流被销毁或分配给
- 何时
emit在流上显式调用 - when
flush在流上调用并且流缓冲已emit_on_sync启用。
一个简单的选择是拥有一个特殊类型,osyncstream当与 一起使用时创建一个新对象<<:
class _synced_cout {
public:
template <class T>
std::osyncstream operator<<(const T& value) const {
std::osyncstream synced_cout_stream(std::cout);
synced_cout_stream << value;
return synced_cout_stream;
}
};
当返回的临时文件被销毁时,写入它的所有内容都将转移到std::cout.
THE END
二维码