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...
the standard C printf() and scanf() functions use stdio so they are thread-safe.
Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With