Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Qt's QBuffer thread safe?

I am using QBuffer in ReadWrite mode. One worker QThread pushes data in the buffer and another QThread reads from it.

Does QBuffer guarantee thread-safety or do I need to derive from QBuffer and add mutex stuff?

like image 440
S B Avatar asked Dec 20 '22 12:12

S B


2 Answers

To quote Mark Summerfield's book C++ GUI Programming with Qt 4:

Qt's thread-safe classes include QMutex, QMutexLocker, QReadWriteLock, QReadLocker, QWriteLocker, QSemaphore, QThreadStorage, and QWaitCondition. In addition, parts of the QThread API and several other functions are thread-safe, notably QObject::connect(), QObject::disconnect(), QCoreApplication::postEvent(), and QCoreApplication::removePostedEvents().

Qt expects that you will use locking mechanisms around most of it's classes. The docs will say "All functions are thread-safe" if they are, and the individual functions will also specify "is thread-safe".

Notes on Qt Classes

Many Qt classes are reentrant, but they are not made thread-safe, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. For example, QString is reentrant but not thread-safe. You can safely access different instances of QString from multiple threads simultaneously, but you can't safely access the same instance of QString from multiple threads simultaneously (unless you protect the accesses yourself with a QMutex).

Some Qt classes and functions are thread-safe. These are mainly the thread-related classes (e.g. QMutex) and fundamental functions (e.g. QCoreApplication::postEvent()).

Because QBuffer is a direct subclass of QIODevice I would especially expect it not to be thread-safe, but there are container classes that are thread-safe for read-access, but would require locking for write access:

Container Classes

The container classes are implicitly shared, they are reentrant, and they are optimized for speed, low memory consumption, and minimal inline code expansion, resulting in smaller executables. In addition, they are thread-safe in situations where they are used as read-only containers by all threads used to access them.

like image 55
jdi Avatar answered Dec 23 '22 01:12

jdi


QBuffer isn't the best way to communicate between threads as writing to it makes the buffer grows, but reading from it doesn't delete the data at the beginning.

You could instead use signal/slot with a QByteArray parameter, use QLocalSocket or write a thread-safe ring buffer class derived from QIODevice yourself.

like image 42
alexisdm Avatar answered Dec 23 '22 02:12

alexisdm