QBufferをReadWrite
モードで使用しています。1人のワーカーQThread
がデータをバッファーにプッシュし、別のワーカーがバッファーQThread
から読み取ります。
スレッドセーフを保証しますか、それともミューテックスのものQBuffer
から派生して追加する必要がありますか?QBuffer
QBufferをReadWrite
モードで使用しています。1人のワーカーQThread
がデータをバッファーにプッシュし、別のワーカーがバッファーQThread
から読み取ります。
スレッドセーフを保証しますか、それともミューテックスのものQBuffer
から派生して追加する必要がありますか?QBuffer
MarkSummerfieldの著書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
特にスレッドセーフではないと予想されますが、読み取りアクセスではスレッドセーフであるが、書き込みアクセスではロックが必要なコンテナクラスがあります。
コンテナクラスは暗黙的に共有され、再入可能であり、速度、低メモリ消費、最小限のインラインコード拡張のために最適化されているため、実行可能ファイルが小さくなります。さらに、それらにアクセスするために使用されるすべてのスレッドによって読み取り専用コンテナーとして使用される状況では、スレッドセーフです。
QBuffer
スレッドに書き込むとバッファが大きくなるため、スレッド間で通信するための最良の方法ではありませんが、スレッドから読み取ると、最初にデータが削除されることはありません。
QByteArray
代わりに、パラメータでsignal / slotを使用したり、自分QLocalSocket
から派生したスレッドセーフなリングバッファクラスを使用または記述したりできQIODevice
ます。
これはQIODeviceを拡張し、そこにあるドキュメントにはQIODeviceのすべてのメソッドが再入可能であると記載されていますが、その上にスレッドセーフは指定されていません。QBufferがこれ以上何も言及していないことを考えると、QBufferはスレッドセーフではないと思います。
Qtのスレッド間で通信する最も簡単な方法は、他のスレッドのイベントキューにイベントを投稿することです。これは、他のスレッドがイベントループをスピンすることを前提としています。通常は新しいデータなどをチェックする場所で定期的にスピンするだけです。
他のいくつかの投稿者が指摘しているように、QBufferは、スレッドセーフの問題に関係なく、この作業には不適切なツールです。
Qtにプロセス内ローカルパイプはありますか?意図された目的により適したQIODeviceベースのFIFOキューについて説明します(ただし、スレッドセーフメカニズムは含まれていません)。