1

GUI を処理するメイン スレッドとネットワーク接続を管理する 2 番目のスレッドの 2 つのスレッドを持つ Qt アプリケーションがあります。スレッドコードは次のとおりです。

void thread::run()
{
    QTcpServer server;

    server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));

    //...
}

OnConnect()アプリケーションの先頭にブレークポイントを置いてデバッグするOnConnect()と、メイン スレッドから呼び出されていることが通知されます。

OnConnect()と同じスレッドで実行するにはどうすればよいQTcpServerですか?

4

2 に答える 2

4

より完全な答えを得るには、シグナルスロット接続とスレッドコンテキストがどのように相互作用するかをもう少し深く見てください。基本的に、より多くの接続 (自動接続) の場合、エミッターとレシーバーの両方が同じスレッド コンテキストにある場合、スロットは直接呼び出されます。スロットを含むオブジェクト。この場合、キューに入れる必要があります。これは、スレッドがそれ自体ではなく、メイン アプリケーションのスレッド コンテキストの一部であることを意味します。これは、 Qt がそのスレッド化の概要を提供するドキュメントによって強化されます。ここでは、QThread インスタンスは、それが表すスレッド コンテキストではなく、それを作成したスレッド コンテキストによって「所有」されていると記載されています。これは、次の 3 つの主な選択肢があることを意味します。

  1. moveToThread() を使用して、スレッドを独自のコンテキストに移動できます。これは、スレッドを破棄するコンテキストに戻さない限り、スレッドを削除するときに問題を引き起こす可能性があることに注意してください。これは、ソーススレッドのコンテキストでのみ実行できるため、実行関数が終了する前に実行する必要があります。
  2. QThread インスタンスは、スレッド自体の一部としてではなく、スレッドへのハンドルとして扱うことができます。新しいスレッドのコンテキストで何かを行う必要がある場合は、それらを処理する別のオブジェクトを作成し、それらを新しいスレッドのコンテキスト (run 関数内) でインスタンス化します。これは私がお勧めするものです。
  3. 直接接続を強制します。これは、スロットで実行されているコードがスレッドセーフであることを確認する必要があることを意味し、これらの関数をスレッドセーフにする Qt の組み込みメソッドを無視します。 これはあなたがしたことです
于 2010-10-04T17:27:35.783 に答える
0

Qt::DirectConnectionの最後のパラメータとして渡していなかったことが問題だったようですconnect()

それを追加した後、それは機能しました。

于 2010-10-02T05:15:36.447 に答える