Qt は必要なものをすべて提供します。ニーズは次のとおりです。
TableView
クラスのデータ メンバーへのスレッド セーフな (シリアル化された) アクセス。
ネットワーク プリミティブ。
ネットワーク アクセスを別のスレッドに移動する柔軟性。
おそらくネットワークからデータを受信しており、arr
メンバーを更新したいと考えています。次のようにします。
QObject
の派生クラスを作成します。Processor
これには、ネットワーク接続をセットアップするスロット (おそらくQTcpServer
) があります。QTcpSocket
接続時に、データを交換するために使用します。すべてのデータ処理がクラスのスロットで行われていることを確認してください。ベクトルで更新する新しい値がある場合は、emit
単にhasFloat(int,float)
.
setFloat(int,float)
にスロットを追加しTableView
ます。
setFloat
のインスタンスからの信号を に接続Processor
しますTableView
。
この時点で、すべてが GUI スレッドで実行されますが、ネットワーク データを待機しないため、コードはノンブロッキングです。QTcpServer
とによって発せられた信号に応答しますQTcpSocket
。必要に応じて、そのままにしておくことができます。
Processor
ベンチマークでメインスレッドが CPU バウンドであることが示されている場合、クラスを別のスレッドで実行するのは簡単です。
int main(int argc, char** argv) {
bool separateThread = true;
QApplication app(argc, argv);
TableView view;
Processor proc;
connect(&proc, SIGNAL(hasFloat(int,float)), &view, SLOT(setFloat(int,float)));
QThread thread;
if (separateThread) {
thread.start();
proc.moveToThread(&thread);
}
view.show();
const bool rc = app.exec();
if (thread.isRunning()) {
thread.exit(); // tells the event loop in the thread to bail out
thread.wait(); // waits for the above to finish
}
return rc;
}
スレッド全体に物事を広げると、どういうわけか魔法のようにスレッドが良くなるという誤解があります。スレッドは、実行中の計算の CPU バウンドとブロック API という特定の問題に対するソリューションです。処理が些細なものであれば、CPU バウンドになる可能性は低くなります。Qt はノンブロッキングの非同期ネットワーキングを提供します。したがって、通常、2 番目のスレッドをスピンする必要はまったくありません。
そうでないことを示すには、最初に実数を表示する必要があります。それ以外の場合は、スレッド化のカーゴ カルトに参加しています: ああ、それはネットワークです。別のスレッドに移動する必要があります。いいえ、必ずしもそうではありません。最初に測定します。あなたがしていることを理解してください。
上記のコードのスレッド セーフの理由は次のとおりです。Processor
インスタンスを別のスレッドに移動すると、Qt はタイプを使用してすべてのシグナルスロット接続を再接続しQt::QueuedConnection
ます。したがって、 がProcessor
出力されると、内部的に、存在するスレッド (この場合は GUI スレッド)hasFloat
のイベント キューにイベントがキューイングされます。TableView
イベント ループがスピンすると (ここでは、アプリケーションのイベント ループになります)、イベントを取得して への呼び出しを実行しますTableView::setFloat
。これにより、arr
データ メンバーへのアクセスがシリアル化され、複数のスレッドから同時にアクセスされる可能性がなくなります。