简体   繁体   中英

Which are thread safe printing syntaxes in C++, and Qt?

qDebug() and std::cout are considered not to be thread safe since their docs do not mention anything regarding thread safety.

Which are thread safe printing syntaxes in C++, and Qt?

Use an output method that locks a mutex before writing. That way only one thread will write at a time.

#include <iostream>
#include <ostream>
#include <sstream>
#include <mutex>

class Logger {
public:
    // destructor is called when output is collected and
    // the temporary Logger() dies (after the ";").
    ~Logger() {
        Logger::mutex_.lock(); // make sure I am the only one writing
        std::cout << buffer_.str(); // write
        std::cout << std::flush; // push to output
        Logger::mutex_.unlock(); // I am done, now other threads can write
    }

    // funny construct you need to chain logs with "<<" like
    // in std::cout << "var = " << var;
    template <typename T>
    Logger &operator<<(T input) {
        buffer_ << input;
        return *this;
    }

private:
    // collect the output from chained << calls
    std::ostringstream buffer_;

    // mutex shared between all instances of Logger
    static std::mutex mutex_;
};

// define the static variable. This line must be in one .cpp file
std::mutex Logger::mutex_;

int main()
{
    Logger() << "Hello" << " " << "World\n";
    Logger() << 123 << "test\n";
    return 0;
}

http://cpp.sh/3pd5m

Both are thread safe in the sense that they will not cause your program to crash. Also the output is safe in the sense that all characters sent to the stream will be printed to their intentional value, eg

Thread A sends: {a,b,c,d}

Thread B sends: {1,2,3,4}

A valid output can be {a,b,1,2,3,c,d,4} but you will never see a character not from that set eg {m}.

In order to serialize your output you should use mutual exclusion the least through some globally accessible mechanism.

eg a simple class may well do that

class printsafe{
private:
  typedef std::mutex t_lock;
  static t_lock l_print;
public:
  static void print(std::string const & s}
  {
     std::lock_guard<printsafe::t_lock> l;
     std::cout << s ; // or qDebug(s.c_str());
  }
};

Now your output will be either {abcd1234} or {1234abcd} given that

thread A sends: abcd

thread B sends: 1234

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM