How to easily make std::cout thread-safe?

前端 未结 9 757
庸人自扰
庸人自扰 2020-12-02 10:52

I have a multi-threaded application, which heavily uses std::cout for logging without any locking. In such a case, how can I easily add lock mechanism to make <

9条回答
  •  鱼传尺愫
    2020-12-02 11:14

    A feasible solution uses a line-buffer for each thread. You might get interleaved lines, but not interleaved characters. If you attach that to thread-local storage, you also avoid lock contention issues. Then, when a line is full (or on flush, if you want), you write it to stdout. This last operation of course has to use a lock. You stuff all this into a streambuffer, which you put between std::cout and it's original streambuffer.

    The problem this doesn't solve is things like format flags (e.g. hex/dec/oct for numbers), which can sometimes percolate between threads, because they are attached to the stream. It's nothing bad, assuming you're only logging and not using it for important data. It helps to just not format things specially. If you need hex output for certain numbers, try this:

    template
    std::string hex(integer_type v)
    {
        /* Notes:
        1. using showbase would still not show the 0x for a zero
        2. using (v + 0) converts an unsigned char to a type
           that is recognized as integer instead of as character */
        std::stringstream s;
        s << "0x" << std::setfill('0') << std::hex
            << std::setw(2 * sizeof v) << (v + 0);
        return s.str();
    }
    

    Similar approaches work for other formats as well.

提交回复
热议问题