c++ - 如何创建一个新类来继承 ostream 并将其用作 cout 但带有锁

标签 c++ multithreading cout ostream

我使用 std::cout 在控制台上打印日志。由于程序是多线程的,如果我在cout后使用多个"<<"操作,打印结果会很乱。


例如,如果一个线程执行cout<< "A" << "B" << endl;另一个线程可能会执行 cout << "C";在 A 和 B 之间。结果将是“ACB”。


因此我要写一个新的类来继承ostream (实际上是 basic_ostream<char, char_traits<char>>)并在初始化 cout 时添加一个锁,因此打印输出应遵循正确的顺序。

最佳答案

一种选择是创建一个类,该类持有对流的引用,但在其整个生命周期内持有锁。这是一个简单的例子:

#include <iostream>
#include <mutex>

struct LockedOstream {
    std::lock_guard<std::mutex> lg_;
    std::ostream& os_;
    LockedOstream(std::mutex& m, std::ostream& os)
      : lg_{m}
      , os_{os}
    { }
    std::ostream& stream() const { return os_; }
};

int main()
{
    std::mutex m;
    LockedOstream(m, std::cout).stream() << "foo " << "bar\n";
    //                        ^ locked now                   ^ unlocked now
}

只要形成单个输出“单元”的所有打印都发生在同一语句中,这就有效。


编辑:实际上,继承版本比我最初预期的要好得多:

#include <iostream>
#include <mutex>

class LockedOstream : public std::ostream {
    static std::mutex& getCoutMutex()
        // use a Meyers' singleton for the cout mutex to keep this header-only
    {
        static std::mutex m;
        return m;
    }

    std::lock_guard<std::mutex> lg_;

  public:
    // Generic constructor
    // You need to pass the right mutex to match the stream you want
    LockedOstream(std::mutex& m, std::ostream& os)
      : std::ostream(os.rdbuf())
      , lg_{m}
    { }

    // Cout specific constructor
    // Uses a mutex singleton specific for cout
    LockedOstream()
      : LockedOstream(getCoutMutex(), std::cout)
    { }
};

int main()
{
    LockedOstream() << "foo " << "bar\n";
    //            ^ locked now          ^ unlocked now
}

顺便说一句:

(虽然后者有时会引起争议,但至少了解并做出明智的选择是个好主意)。

关于c++ - 如何创建一个新类来继承 ostream 并将其用作 cout 但带有锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55489008/

相关文章:

c++ - 如何在 C++ 中将复杂的<float>变量转换为 float ?

c++ - 如何从一段 HTML 源代码中获取字体颜色?

Java - 分阶段线程

c++ - 有命名空间和没有命名空间的加载时间差异

c++ - std::ostream 作为可选 (!) 函数参数

c++ - 如何将 CString 转换为 CByteArray?

c++ - 使用 C++ 根据行中的第一个字符串查找行(仅一个)

java - 与 Scala/Akka Actor 相比,Java 线程有多重?

c# - 捕获线程未处理的异常

c++ - 找到一个简单打印功能的大哦估计