Mar*_*sSK 3 logging multithreading mutex stdout c++11
我需要在我的日志记录应用程序中锁定 stdout,以防止在记录到 stdout 的多线程应用程序中出现字符串交错。无法弄清楚如何使用移动构造函数或 std::move 或 sth else 将 unique_lock 移动到另一个对象。
我创建了用于设置配置和封装的对象,并想出了如何使用静态 std::mutex 锁定 stdout 以锁定这些对象(称为分片)。
像这样的东西对我有用:
l->log(1, "Test message 1");
Run Code Online (Sandbox Code Playgroud)
虽然这很好并且可以用模板和可变数量的参数来实现,但我想接近更多类似流的可能性。我正在寻找这样的东西:
*l << "Module id: " << 42 << "value: " << 42 << std::endl;
Run Code Online (Sandbox Code Playgroud)
我不想强迫用户使用连接和 to_string(42) 预先计算字符串我只想找到一种锁定标准输出的方法。
到目前为止,我的方法是创建 operator << 和另一个对象锁定流,正如其他答案中所建议的那样。事情是我无法弄清楚如何将互斥锁移动到另一个对象。我的代码:
locked_stream& shard::operator<<(int num)
{
static std::mutex _out_mutex;
std::unique_lock<std::mutex> lock(_out_mutex);
//std::lock_guard<std::mutex> lock (_out_mutex);
std::cout << std::to_string(num) << "(s)";
locked_stream s;
return s;
}
Run Code Online (Sandbox Code Playgroud)
将输入输出到 std::cout 后,我希望将锁移到对象流中。
在这种情况下,我会小心不要在函数中使用静态锁,因为您会为您创建的每个流操作符获得不同的锁。
您需要的是在创建流时锁定一些“输出锁”,并在流被销毁时解锁它。如果您只是包装 std::ostream,则可以利用现有的流操作。这是一个有效的实现:
#include <mutex>
#include <iostream>
class locked_stream
{
static std::mutex s_out_mutex;
std::unique_lock<std::mutex> lock_;
std::ostream* stream_; // can't make this reference so we can move
public:
locked_stream(std::ostream& stream)
: lock_(s_out_mutex)
, stream_(&stream)
{ }
locked_stream(locked_stream&& other)
: lock_(std::move(other.lock_))
, stream_(other.stream_)
{
other.stream_ = nullptr;
}
friend locked_stream&& operator << (locked_stream&& s, std::ostream& (*arg)(std::ostream&))
{
(*s.stream_) << arg;
return std::move(s);
}
template <typename Arg>
friend locked_stream&& operator << (locked_stream&& s, Arg&& arg)
{
(*s.stream_) << std::forward<Arg>(arg);
return std::move(s);
}
};
std::mutex locked_stream::s_out_mutex{};
locked_stream locked_cout()
{
return locked_stream(std::cout);
}
int main (int argc, char * argv[])
{
locked_cout() << "hello world: " << 1 << 3.14 << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是 ideone:https ://ideone.com/HezJBD
另外,请原谅我,但由于在线编辑器很笨拙,所以上面会有空格和制表符的混合。
归档时间: |
|
查看次数: |
1318 次 |
最近记录: |