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データ メンバーへのアクセスがシリアル化され、複数のスレッドから同時にアクセスされる可能性がなくなります。