0

QT アプリケーションにタイムアウトを実装しようとしています。QThread を使用して操作 (タイムアウトが必要なタスク) を実行し、QElapsedTimer を使用して操作の実行を待機している経過時間をカウントしました。以下はコードスニペットです

QElapsedTimer timeoutTimer;   // Timer to count the elapsed time waiting for the operation to complete.
long timeoutInterval=10000
MyThread mThread();   // QThread implementation
timeoutTimer.start(); 
mThread.start();   

while((timeoutTimer.elapsed() < timeoutInterval) &&  mThread.isRunning()){
    sleep(5);
}


if(mThread.isRunning()){
  mThread.terminate();
}

ここで、タスクが完了せずにタイムアウトが発生すると、「スレッドの実行中に破棄されました」というメッセージが表示され、アプリケーションがクラッシュします。QThread の terminate() 関数を呼び出そうとしましたが、Windows では動作していますが、Linux ではセグメンテーション エラーが発生します。

4

2 に答える 2

3

quit()あなたのスレッドでは機能しないと述べたので、QThread::runメソッドを再実装し、実装でイベントループを使用していないと思います。ドキュメントが言うように:

QThread は完全に機能するスレッド管理機能を提供するため、ほとんどの場合、QThread をサブクラス化する必要はありません。それにもかかわらず、高度なスレッド管理を実装したい場合は、QThread をサブクラス化できます。これは、新しいメンバー関数をサブクラスに追加するか、run() を再実装することによって行われます。QThread の run() 関数は、アプリケーションの main() 関数に似ています — スレッドが開始されると実行され、スレッドが戻るとスレッドは終了します。

注: Qt 4.4 より前では、QThread を並列処理に使用する唯一の方法は、QThread をサブクラス化し、run() 内に処理コードを実装することでした。このアプローチは現在、悪い習慣と見なされています。QThread は、データを処理するのではなく、スレッドのみを管理する必要があります。

したがって、サブクラス化しないでくださいQThread。標準イベントループとシグナルスロットシステムを使用して、スレッドを使用できます。また、タスクに対して実行できるかのように、より高度なインターフェイスを使用することもできQRunnableます。

イベントループの利点を再実装して排除したいことが確実な場合はQThread::run、スレッドを手動で停止する必要があります。たとえば、ブール値のフラグを使用bool need_to_stopして、スレッドの実行中に定期的にその値を確認できます。スレッドを停止する場合は、フラグの値を true に設定してから を呼び出しますQThread::wait()QThread::runフラグの値が原因で が終了すると、スレッドは停止して戻りwait()ます。ただし、新しいスレッドと GUI スレッドの両方から同時に 1 つのフラグを単純に使用することはできないことに注意してください。のような同期メカニズムが必要ですQMutex。したがって、このことは複雑すぎます。本当に低レベルのことをしたくない場合は、QThread をサブクラス化しないでください。

于 2013-06-05T09:18:36.637 に答える
1

void QThread::quit ()ドキュメントに記載されているように使用してみてください

Tells the thread's event loop to exit with return code 0 (success). Equivalent to calling QThread::exit(0).
This function does nothing if the thread does not have an event loop.
于 2013-06-05T06:07:46.047 に答える