Qtにおけるスレッド間,スレッドとプロセス間の通信

1997 ワード

前言:スレッドの作成は、プライマリ・プロセスにあまり関連のないタスクを単独で実行するためであり、このタスクは時間がかかります.スレッドは、いくつかの入力が出力されていないタスクを処理することができますが、他のスレッドやプロセスに結果を出力する必要があるタスクを処理する場合があります.例えば、大量のデータの演算を処理する場合は、計算結果を対応するスレッドやプロセスに時間分割して返す必要があります.スレッドとメインプロセスとの間の信号スロットメカニズムは、スレッドがメインプロセスでインスタンス化されているため、メインプロセスに接続される.信号スロット機構の応答はサブスレッドがrun関数を実行する必要はない.
Qtスレッド間でデータを共有するには、主に2つの方法があります.
1)共有メモリを使用します.すなわち、グローバル変数などの2つのスレッドが共有できる変数を使用して、2つのスレッドが変数にアクセスして変更することができ、データの共有の目的を達成することができます.
2)singal/slotメカニズムを用いて,あるスレッドから別のスレッドにデータを渡す.
第1の方法は一般的な方法であり,第2の方法はQT特有であり,以下ではsingal/slot機構を主に紹介する.
スレッド間singal/slotメカニズム通信のルール:
1)ライン間で信号スロットを用いて通信する場合、スロットパラメータはメタデータタイプのパラメータを用いなければならない.メタデータは、QTに既に存在するデータ型を表す.
2)Qt内生のメタデータタイプ、例えばint double QStringなど;
3)カスタムデータ型を使用する場合は、connectの前にメタデータ型として登録する必要があります.
4)スレッド間で参照パラメータを「信号とスロット」で渡す場合はconstを付ける.const文字定数は定数領域に存在し,ライフサイクルはプログラムと同じ長さであるからである.これにより、slot呼び出し時にパラメータの実行期間が過ぎて参照が無効になることを回避できます.
カスタム・データを使用してメタデータ・タイプとして登録するには(受信者で次の手順を使用します):
  • (カスタムTextAndNumberタイプを例に)
  • は、このタイプの上部に、#include
  • を含むタイプをカスタマイズする.
  • タイプ定義完了後、宣言:Q_を追加DECLARE_METATYPE(TextAndNumber);
  • main()関数にこのタイプを登録します:qRegisterMetaType("TextAndNumber");
  • このタイプの参照を使用する場合は、qRegisterMetaType("TextAndNumber&");
  • が参照する宣言は、5に示すように、タイプと後ろの文字の間に差があります&、他のタイプの宣言は<>の内容と「」の間の文字と同じです.

  • 第2のステップのQMetaTypeは、送信者(データを送信するスレッド)でカスタマイズされ、情報を含むQMetaTypeを受信者(データを受信するスレッド)に送信する定義を宣言する.
     
    QTスレッド-スレッド間、スレッド-プロセス間の通信singal/slotメカニズムの例:
    QObject::connect(&myThread,SIGNAL(addRes(int)),this,SLOT(showRes(int)));

    まとめ:
  • Qtの信号スロット関数は、QtのタイプとC++が提供する組み込みの基本タイプ、例えばint double floatなどをデフォルトでサポートし、C++のstd::string std::vectorカスタムstructタイプはまったくサポートされていません.だからQtで提供するQ_が必要ですDECLARE_METATYPEとqRegisterMetaTypeは、カスタムタイプとC++の他のタイプを宣言して登録します.
  • マルチスレッド間の信号スロット伝達は、connectの際にQt::QueuedConnectionの方式で行う必要があります.そうでなければ、Qt::DirectConnectionの方式で受信者UIスレッドはバックグラウンドスレッドからの信号を長時間受け取れないか、信号が直接失われるかは可能な
  • です.