我正在尝试创建一个具有std :: ofstream和std :: mutex的类,这个类被锁定和解锁以控制对ofstream的访问。
基本上我想要一个类thread_safe_ofstreamwith<<运算符所以我可以使用它:
thread_safe_ofstream ofs;
ofs << "debug info from different threads" << std::endl;
所以我知道我需要一个运算符&lt;&lt;超载。虽然这个运营商有足够的信息&lt;&lt;对于&lt;&lt;的右侧的类,我找不到任何关于如何实现自己类似ostream的文档&lt;&lt;输入
我知道以下代码无法正常工作,因为无论输入/输出要求是什么&lt;&lt;有,但这是我需要的课程的精神。
Class thread_safe_ofstream
{
std::mutex mu;
std::ofstream stream;
template<typename T>
operator<<(T& thing)
{
mu.lock();
stream << thing;
mu.unlock();
}
};
这样一个thread_safe_ofstream就可以从多个线程中解决而没有问题(我的希望是)。
答案 0 :(得分:0)
那样的东西?
template<typename T>
thread_safe_ofstream& operator<<(const T& thing)
{
std::lock_guard<std::mutex> guard(mu);
stream << thing;
return *this;
}
但是,通常最好将operator <<
实现为自由函数,而不是类成员。
答案 1 :(得分:0)
例如,您可以使用此类实现:
class thread_safe_ofstream
{
std::mutex mu;
std::ofstream stream;
template<typename T>
void put(const T& thing) {
std::lock_guard<std::mutex> lock(mu);
stream << thing;
}
friend template<typename T>
thread_safe_ofstream& operator<<(thread_safe_ofstream& tsof, const T& value) {
tsof.put(value);
return tsof;
}
};
答案 2 :(得分:0)
这是一个完整的类,它将打印来自ts_ofs << "print this message" << std::endl
之类的命令的大部分无文本文本,但后续<<
之间的另一个线程可能会开始打印。我怀疑可能有一个修复,但我不知道该怎么做。灵感来自this post。
struct ts_ofstream
{
std::ofstream ostream;
std::mutex mu;
//This is only for testing, you can initialize ostream however/wherever you like.
void init(bool test = false)
{
ostream = std::ofstream("C:/Users/Joey/Desktop/THREAD_DEBUG.txt", ios::out);
if (test)
{
ostream << "Testing stream ";
ostream << std::endl;
ostream << "Testing complete" << std::endl;
}
}
template <typename T>
friend ts_ofstream& operator<<(ts_ofstream& s, const T& x);
// function that takes a custom stream, and returns it
typedef ts_ofstream& (*MyStreamManipulator)(ts_ofstream&);
// take in a function with the custom signature
ts_ofstream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}
// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static ts_ofstream& endl(ts_ofstream& stream)
{
// print a new line
stream.ostream << std::endl;
return stream;
}
// this is the type of std::ofstream
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
ts_ofstream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(this->ostream);
return *this;
}
};
template<typename T>
ts_ofstream & operator<<(ts_ofstream & s, const T & x)
{
std::lock_guard<std::mutex> lock(s.mu);
s.ostream << x;
return s;
}