Is qDebug() thread-safe?

c++, multithreading, qdebug, qt

Solution

Following are my answer and comments:

If the documentation of qDebug() does not mention whether it is thread-safe or not, we should assume it is not. The answer is likely platform-dependent: how qDebug() is implemented at the system level (Linux, Windows, ...).

Instead of the broader question of thread-safety, I think you were asking a more specific question like this: "Will the use of qDebug() in a multi-threaded application lead to interleaved output lines?" The answer is "Yes, occasionally." as demonstrated by the results produced by @dmcontador above. And the probability increases when the strings to be printed out are getting longer, as explained by @quetzalcoatl above.

The answer does not depend on whether you use qDebug("...") or qDebug() << "...", as both will finally call the system-level implementation code.

It is not easy for me to produce interleaved output lines using your original example code. So I have created a new example as shown below:

#include <QCoreApplication>
#include <QtConcurrent>

#define MAX_ITERS 10
#define MAX_LEN   10000

void print_a()
{
    QString a(MAX_LEN, 'a');

    for(int i = 0; i < MAX_ITERS; ++i) {
        qDebug().noquote() << a;
    }
}

void print_b()
{
    QString b(MAX_LEN, 'b');

    for(int i = 0; i < MAX_ITERS; ++i) {
        qDebug().noquote() << b;
    }
}

int main(int argc, char * argv[])
{
    QCoreApplication a(argc, argv);
    QtConcurrent::run(print_a);
    QtConcurrent::run(print_b);
    return 0;
}

The probability increases when you increase MAX_LEN.

- A follow-up question would be: "How to use qDebug() to produce non-interleaved output lines?" One solution would be to use QMutex on each and every qDebug() line. Note that I have not tried this solution which is not practical.

Problem

Is `qDebug()` thread-safe? By thread-safe I don't just mean not-crashing, but also if I call `qDebug()` from different threads, is it possible for the output to become mixed-up? I tested it with this code, and it doesn't appear to be so, however, I couldn't find anywhere in the documentation where they talk about this. This is my test code: ``` #include <QtConcurrent> #include <QApplication> void print_a() { for (int ii = 0; ii < 10000; ii++) { qDebug("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } } void print_b() { for (int ii = 0; ii < 10000; ii++) { qDebug("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); QtConcurrent::run(print_a); QtConcurrent::run(print_b); return a.exec(); } ``` There were no 'a' and 'b' mixed in the same line anywhere, but I'm still not sure if it's 100% thread safe...

Original source

Related problems