我在ReadWrite
模式下使用QBuffer。一个工作人员QThread
将数据推入缓冲区,另一个QThread
从中读取数据。
QBuffer
是否保证线程安全,还是需要从QBuffer
派生并添加互斥内容?
答案 0 :(得分:8)
引用Mark Summerfield的书C++ GUI Programming with Qt 4:
Qt的线程安全类包括QMutex,QMutexLocker,QReadWriteLock, QReadLocker,QWriteLocker,QSemaphore,QThreadStorage和 QWaitCondition。另外,部分QThread API和几个 其他函数是线程安全的,特别是QObject :: connect(), QObject :: disconnect(),QCoreApplication :: postEvent()和 QCoreApplication :: removePostedEvents()。
Qt期望你将在其大部分类中使用锁定机制。文档将说“所有函数都是线程安全的”,如果它们是,并且各个函数也将指定“是线程安全的”。
许多Qt类都是可重入的,但它们不是 使线程安全,因为使它们线程安全将导致 反复锁定和解锁QMutex的额外开销。对于 例如,QString是可重入但不是线程安全的。你可以放心 从多个线程访问QString的不同实例 同时,但你不能安全地访问相同的实例 来自多个线程的QString同时(除非你保护 使用QMutex访问自己)。
有些Qt类和函数 线程安全的。这些主要是线程相关的类(例如QMutex) 和基本功能(例如QCoreApplication :: postEvent())。
因为QBuffer
是QIODevice
的直接子类,我特别希望它不是线程安全的,但是有些容器类对于读访问是线程安全的,但需要锁定用于写访问:
容器类是隐式共享的,它们是可重入的,并且 它们针对速度,低内存消耗和最小化进行了优化 内联代码扩展,导致较小的可执行文件。此外, 它们在以只读方式使用的情况下是线程安全的 用于访问它们的所有线程的容器。
答案 1 :(得分:2)
QBuffer
不是线程之间进行通信的最佳方式,因为写入它会使缓冲区增长,但从中读取并不会在开始时删除数据。
您可以改为使用带有QByteArray
参数的signal / slot,使用QLocalSocket
或自己编写一个源自QIODevice
的线程安全环缓冲类。
答案 2 :(得分:1)
这扩展了QIODevice,并且那里的文档指出QIODevice上的所有方法都是可重入的,但是没有指定任何线程安全。鉴于QBuffer没有提及任何其他内容,我希望QBuffer不是线程安全的。
答案 3 :(得分:0)
Qt中线程之间通信的最简单方法是将事件发布到另一个线程的事件队列。这假设另一个线程旋转一个事件循环。它只需要定期旋转它,你通常会检查新数据等。
答案 4 :(得分:0)
正如其他一些发帖人所指出的那样,无论线程安全问题如何,QBuffer都是错误的工具。
Is there an intra-process local pipe in Qt?描述了一个基于QIODevice的FIFO队列,该队列更适合于预期的目的(尽管它不包括任何线程安全机制)