简体   繁体   English

C ++和Qt中哪些是线程安全打印语法?

[英]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. qDebug()std::cout被认为不是线程安全的,因为他们的文档未提及任何有关线程安全的内容。

Which are thread safe printing syntaxes in C++, and Qt? C ++和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 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} 线程A发送:{a,b,c,d}

Thread B sends: {1,2,3,4} 线程B发送:{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}. 有效的输出可以是{a,b,1,2,3,c,d,4},但是您永远不会看到不是来自该集合的字符,例如{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 现在您的输出将是{abcd1234}或{1234abcd},因为

thread A sends: abcd 线程A发送:abcd

thread B sends: 1234 线程B发送:1234

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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