問題タブ [qeventloop]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
qt - 他のスレッドが大きなループでビジー状態になっているため、QTimer が遅延して起動する
環境の概要: qt で記述されたアプリケーションを実行するデバイスがあります。これには、データベース操作 (SQlite) を処理するメイン スレッドと、ネットワーク操作 (3G 経由) 用の別のスレッドがあります。メイン スレッド イベント ループは QCoreApplication::exec によって実行され、ネットワーク操作を処理する他のスレッドは QThread::exec によって実行されます。ところで、ソケット スレッド アフィニティは開始後に変更されます (例: moveToThread(socketThreadPtr))
問題の概要: データベースから約 10,000 レコードを選択するために、メイン スレッドがループでビジー状態になり、そのループに約 +30 秒かかります。ネットワーク スレッドには、期限が切れるたびにキープ アライブ メッセージを送信する必要がある 15 秒のタイマーがあります。問題は、timeout() シグナルのスロットがループの終了後にのみ実行されることです。
今までの解決策 (ただし、満足のいくものではありません): レコードを選択するループで QCoreApplication::processEvents を呼び出すと、問題は解決しますが、この回避策の代わりに解決策が存在するかどうか疑問に思います。
注意: キープアライブ メッセージを送信するコマンドを与えるタイマー、シグナル、およびスロットは、現在メイン スレッドで処理されます (ただし、読み取り/書き込みはネットワーク スレッドで行われます)。また、タイマーをネットワーク スレッドに移動しましたが、メイン スレッドにある場合と同じ結果が得られました。
c++ - スロット引数が (時々) 無効です
10〜20回のシグナル呼び出しの1つで、スロットに無効な引数があります。問題は次のように要約されます
QCoreApplication::notifyInternal2
これが発生した場合、 (たとえば)次のようなクラッシュ ダンプが表示され ます。
しかしevent->args
、無効のようです。
プラットフォームは Win64、qt のバージョンは 5.6.1、コンパイラは vs2015 です。リリース。何かご意見は?ありがとう。
multithreading - Qt のマルチスレッドとイベント ループについて
Qt マルチスレッドと Qt 4.8 でのイベント ループを理解するのに役立つ説明を探しています。また、私は一般的にスレッド化が初めてなので、それが私の問題の一部であると付け加えます。
私の現在の状況は、QTMultiMedia-QAudioOutput を使用して頻繁にサウンドを再生する必要がある Qt アプリを持っていることです。MainGuiとAudioWorkerの 2 つのクラスがあります。AudioWorker を呼び出してサウンドを "play()" したいことがよくあります。
サウンドが再生される前にプロセスが終了しないように、どうやら QAudioOutput にはイベント ループが必要です。したがって、スレッドが役立つことを理解しています。
スレッドを正しく理解していれば、生成されたスレッドは、何らかの方法で切り離されない限り、それを作成した関数よりも長く生きることはできませんか? MainGui クラスでサウンドを再生する通知を受信し、AudioWorker で play() を呼び出すスロット接続を介して新しいスレッドを生成した場合、MainGui 通知関数が終了すると、イベント ループを持つスレッドが終了することはありませんか? これが事実である場合、どちらにしても MainGui はイベント ループを必要とするでしょうか?
確かに私は何かが欠けていますか?どうにかしてスレッドをデタッチする必要がありますか?デタッチに関する Qt ドキュメントにはあまり記載されていません。単純な音を鳴らすためだけに、このプロセス全体が過剰に思えます。
更新しました
play() 関数で QThread を作成することで問題を解決しました。スレッドは、シグナルを送信するまで途中で終了しません。
https://nachtimwald.com/2015/05/02/effective-threading-using-qt/で、隠れているが素晴らしい例を見つけました。
c++ - Qthread deleteLater() プログラムのクラッシュ
QT 4.8: セグメント フォールトと I/O の可能性のあるエラーがコードに多数表示されますが、それらを理解することはできません。print ステートメントから、多くの奇妙で一貫性のない動作を見てきました。これは、おそらく競合状態を示しています。多くの場合、すべてが完璧に機能します。ワーカー デストラクタが呼び出された直後に、メイン接続の deleteLater() の問題を示す I/O エラーが発生することがあります。また、デストラクタで audioOutput を削除しようとすると、何度も機能し、他の試みでデストラクタの途中でランダムにセグメント障害 (または I/O) が発生します。私の問題は、worker cleanup/ connect quit()/deletelater() 呼び出しの 2 つと、毎回独自のイベント ループを作成する必要がある worker の再帰ループに起因する可能性があるため、以前の呼び出しが行われる前に終了信号を発する可能性があると考えています。掃除した?
具体的には、私の質問は次のとおりです。
deleteLater() が I/O の可能性のあるエラーを作成する原因は何ですか?
ワーカークラス内のポインターを削除して、正しい時間(終了)に削除するにはどうすればよいですか?またはQTがこれを処理しますか?
Gui と .h
ワーカー クラスと .h
更新しました:
まだ断続的な問題がありますが、次の行をコメントアウトすると、quit=true の設定と組み合わせていくつかの問題を解決できました。
しかし、これはメモリリークを引き起こす可能性がありますか?
更新 2:
ここで独り言を言っていると思い始めていますが、わかったと思います。これは、ワーカが finished() を発行すると、オープン ループを閉じる quit() シグナルからアンワインドする時間が原因で、ワーカが実際に終了する前にスレッドが finished() を返していたため、タイミングの問題であったようです。そのため、閉じたループごとにワーカーからカスタム シグナルを発行し、これをメインで追跡します。期待どおりの結果を受け取ったら、wait() を解放し、スレッドを削除してからワーカーを削除します。これが正しいかどうかはわかりませんが、機能しているようです。私にはハックのように思えますが、IMO ワーカーが終了するまでスレッドは終了してはならず、無意味に思えます。でもまあ。
qt - QEventLoop が QNetworkReply の終了を同期的に待機していない
サーバーを呼び出す Qt を使用してライブラリを構築しています。HTTP 応答 (QNetworkReply オブジェクト) を待機する同期関数を構築する必要があり、これを実現するために QEventLoop を使用しています。現在、サーバーは呼び出されますが、ループは応答が終了するのを待たず、代わりに空の QNetworkReply オブジェクトを続行します。
まったく同じ関数が、1 つのスレッドと main からこの関数への呼び出しのみを含む、私が構築した単純なテスト プロジェクトで機能します。返信が待たれ、すべてが期待どおりに機能します。しかし、複数のスレッドを含む私のプロジェクトでは、上記のシナリオが発生し、イベント ループは応答を待ちません。要求はサーバーに送信され、そこに表示されますが、関数が既に実行されているため、応答が QNetworkReply オブジェクトに返されません。
これが私の機能のネットワークセクションです。私のプロジェクトでは、statusCode 変数は常に 0 になり、応答は空になりますが、単純なテスト シナリオでは 200 であり、期待される HTTP 応答です。
c++ - QObject子クラスがQGuiApplicationイベントループを検出しない
QObject から派生したクラスで QTimer を開始しようとすると、警告が表示されます
QObject::startTimer: タイマーは QThread で開始されたスレッドでのみ使用できます
そしてタイマーが動かない。ここの回答に基づいて、カスタム クラスが QGuiApplication によって作成された QEventLoop を検出していないようです。
私のmain.cpp
私のクラスA.h
私のclassA.cpp
新しい QEventLoop を作成せずに修正するにはどうすればよいですか?
qt - 奇妙な信号/スロットの動作
(Qt 5.15.2 での作業) 同じスレッドからシグナル (sig_responseReady) を受け取るメソッドがあります。このメソッドの目的は、応答が受信されるまで待機することです。このメソッドがシグナルを待っている間、このメソッドを呼び出すイベントが原因で、メソッドが再度呼び出されます (そのため、イベントループがネストされます)。ただし、スタック上の最初の waitForResponse は、最大 10 秒間 sig_responseReady シグナルを取得しません (理由はわかりません) が、後で呼び出された waitForResponse が最初にシグナルを取得します。
この設計の結果、入れ子になったイベント ループができました。これは、このスタック オーバーフローの投稿によると、スロット/シグナル処理エラーを引き起こし、回避する必要があります。これが私の問題の原因だと思います。
単一のイベントループだけで同じことを達成する設計はありますか? (思いつきません) waitForResponse を呼び出す関数は、waitForResponse が戻るまで一時停止する必要があります。..非同期にすることはできません。以下の関数で eventloop.exec を QCoreApplication::processEvents(QEventLoop::AllEvents,100) に置き換えてみましたが、それでも同じ奇妙な結果が得られます。(したがって、ネストされたイベントループは問題ではないかもしれません...しかし、原因はわかりません)