1

タイムアウト関数呼び出しが必要です。私は主にQt(4.7.3、4.8.5)を使用しているため、Qtで解決策を見つけようとしました。QFuture と QtConcurrent の 2 つのクラスは、必要なものの 99% を実行しているようですが、関数呼び出しをタイムアウトにする可能性が見つかりません。

私の問題: 私はテスター (gtest) を持っていて、無限ループで終了する可能性のある関数をテストします => その問題を修正するためにこれをテストしたい [s] (この関数は内部極値複合体です :-( ). I無限ループがある場合にタイムアウト時間を追加したい => そのため、何かが間違っていること (無限ループ) をテスターに​​伝えることができ、スレッドを終了します。

私はそのようなものを検索しています:

QtConcurrent::run(............,30000 /*30 seconds timeout)*/;

どうすればこれができるか知っている人はいますか? (ネイティブC ++、ブースト、または...で可能であれば、解決策も教えてください)

4

4 に答える 4

1

問題は、スレッドの協力なしにスレッドを安全に終了できないことです。スレッドは、C ランタイム ヒープなどの共有データ構造にアクセスしている可能性があり、スレッドが強制的に終了されると、そのようなデータ構造は変更途中の状態のままになり、本質的に破損します。今後、プログラム内からそれらにアクセスすると、クラッシュまたはさらに悪化する可能性があります。

無限ループのケースは、他の悪いシナリオと決して違いはありません。起動した関数によってプログラムがクラッシュした場合、テスターに​​どのように報告しますか?

あなたの場合、実行しているコードを単に信頼していません。解決策は、オペレーティング システムによって安全な終了が保証されている別のプロセスで起動することです。テスト対象のコードをテスター アプリケーションから切り離すことで、タイムアウトや異常終了など、あらゆる種類の問題を確実に検出できます。

于 2015-11-16T12:33:28.173 に答える
-2

QTimer シグナルをスロットにバインドできます。

auto process = QtConcurrent::run(...);
QTimer& timer = new QTimer();
connect(timer, &QTimer::timeout, [=, &process]() {
  process.cancel();
});
timer->start(3000);

編集: cancel() メソッドは QtConcurrent::run 関数では機能しないため、最も簡単な方法は、ある種の isRunning フラグを使用することです。

bool isRunning = true;
void runnable() {
  while (isRunning) {
    ...
  }
}

auto process = QtConcurrent::run(runnable);
QTimer& timer = new QTimer();
connect(timer, &QTimer::timeout, [=, &isRunning]() {
  isRunning = false;
});
timer->start(3000);
于 2013-11-11T10:28:20.920 に答える
-2

症状を直そうとするのではなく、なぜ無限ループが発生するのかを突き止める必要があると思います。

QtConcurrent::run()スレッドプールを使用してタスクを実行します。スレッドを安全に終了することはできないため、タスクを安全に終了する唯一の方法はスレッドを終了するreturnことです。

それでもタイムアウトが必要な場合は、ループを使用して関数に次のようなものを追加できます。

QTime t;
t.start();

// it's your loop
while( true ) {

    if( t.elapsed() > 30*1000 ) {
        return 1;
    }
    ...
}
于 2013-11-11T10:12:01.163 に答える