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...
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.