簡體   English   中英

C ++和Qt中哪些是線程安全打印語法?

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

qDebug()std::cout被認為不是線程安全的,因為他們的文檔未提及任何有關線程安全的內容。

C ++和Qt中哪些是線程安全打印語法?

寫入之前,請使用可鎖定互斥鎖的輸出方法。 這樣一來,一次只能寫入一個線程。

#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

從它們不會導致程序崩潰的意義上來說,它們都是線程安全的。 同樣,從所有發送到流的字符將被打印到其有意值的意義上說,輸出也是安全的

線程A發送:{a,b,c,d}

線程B發送:{1,2,3,4}

有效的輸出可以是{a,b,1,2,3,c,d,4},但是您永遠不會看到不是來自該集合的字符,例如{m}。

為了序列化您的輸出,您應該至少通過某種全局可訪問的機制使用互斥。

例如,一個簡單的課程就可以做到

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());
  }
};

現在您的輸出將是{abcd1234}或{1234abcd},因為

線程A發送:abcd

線程B發送:1234

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM