Qt的QBuffer线程安全吗?

Is Qt's QBuffer thread safe?

本文关键字:安全 线程 QBuffer Qt      更新时间:2023-10-16

我在ReadWrite模式下使用QBuffer。一个工作者QThread在缓冲区中推送数据,另一个QThread从中读取

QBuffer保证线程安全吗?还是我需要从QBuffer派生并添加互斥对象?

引用Mark Summerfield的著作《用Qt4:进行C++GUI编程》

Qt的线程安全类包括QMutex、QMutexLocker、QReadWriteLock、,QReadLocker、QWriteLocker、QSemaphore、QThreadStorage和Q等待条件。此外,部分QThread API和几个其他函数是线程安全的,特别是QObject::connect(),QObject::disconnect()、QCoreApplication::postEvent()和QCoreApplication::removePostedEvents()。

Qt预计您将在它的大多数类周围使用锁定机制。如果是的话,文档会说"所有函数都是线程安全的",单个函数也会指定"是线程安全"。

关于Qt类的注释

许多Qt类是可重入的,但它们不是使线程安全,因为使它们线程安全会导致重复锁定和解锁QMutex的额外开销。对于例如,QString是可重入的,但不是线程安全的。你可以安全地从多个线程访问QString的不同实例同时,但不能安全地访问的同一实例Q同时来自多个线程的字符串(除非您保护使用QMutex访问自己)。

一些Qt类和函数是线程安全。这些主要是与线程相关的类(例如QMutex)和基本函数(例如QCoreApplication::postEvent())。

因为QBufferQIODevice的直接子类,我特别希望它不是线程安全的,但有些容器类对读访问是线程安全的但对写访问需要锁定:

容器类

容器类是隐式共享的,它们是可重入的,并且它们针对速度、低内存消耗和最小化进行了优化内联代码扩展,产生更小的可执行文件。此外它们在用作只读的情况下是线程安全的容器的所有线程用于访问它们。

QBuffer不是线程之间通信的最佳方式,因为写入它会增加缓冲区,但从中读取并不会在一开始就删除数据。

您可以使用带有QByteArray参数的signal/slot、使用QLocalSocket或自己编写从QIODevice派生的线程安全环形缓冲区类。

它扩展了QIODevicece,那里的文档指出QIODevicee上的所有方法都是可重入的,但没有指定任何线程安全性。考虑到QBuffer没有提到更多内容,我认为QBuffer不是线程安全的。

http://qt-project.org/doc/qt-4.8/qiodevice.html

Qt中线程之间通信的最简单方法是将事件发布到其他线程的事件队列。这假设另一个线程旋转一个事件循环。它只需要在你通常检查新数据等的地方定期旋转。

正如其他几张海报所指出的,无论线程安全问题如何,QBuffer都是错误的工具。

Qt中是否存在进程内本地管道?描述了一个基于QIODevice的FIFO队列,它将更适合预期目的(尽管它不包括任何线程安全机制)