1

ポーリングを行う C++ メソッドにタイムアウトを実装しようとしています。現在、メソッドは次のようになっています (タイムアウトなし)。

do {
    do_something();
    usleep(50);
} while(!is_finished());

ソリューションには、次のプロパティが必要です。

  • システム時間の変更に耐えなければならない
  • ミリ秒単位のタイムアウト (多少のジッターは許容可能)
  • POSIX互換
  • シグナルを使用しないでください (ライブラリの一部であり、副作用を回避します)
  • ブーストを使用する可能性があります

私は現在clock()、このようなことを使用して行うことを考えています:

start = clock();

do {
    do_something();
    usleep(50); // TODO: do fancy stuff to avoid waiting after the timeout is reached

    if(clock() - start > timeout * CLOCKS_PER_SEC / 1000) break;
} while(!is_finished());

これは良い解決策ですか?この種のタスクは頻繁に発生するように思われるため、可能な限り最善の解決策を見つけようとしています。

この種の問題のベストプラクティスと考えられるものは何ですか?

前もって感謝します!

4

2 に答える 2

1

ミリ秒単位の正確なタイムアウトは、特にリアルタイム サポートを提供しない OS では実現できません。

システムの負荷が (一時的であっても) 高い場合、数秒間応答しなくなる可能性があります。標準 (非リアルタイム) システムは、CD-Rom デバイスへのアクセスなど、明らかにばかげた理由で非常に応答しなくなることがあります。

Linux にはいくつかのリアルタイムのバリエーションがありますが、Windows IIRC の場合、唯一のリアルタイム ソリューションには、Windows システムが基本的に仮想マシンで「エミュレート」されて実行されるハードウェアを管理するリアルタイム カーネルがあります。

于 2013-09-21T05:43:30.840 に答える
1

clockポータブルにしたい場合は、正しい選択ではありません。準拠しているシステムでは、これはプロセスで使用された CPU 時間であり、Windows ではウォール クロック時間のようです。またusleep、現在の POSIX では廃止されており、使用することになっていますnanosleep

より広い範囲のプラットフォームに適した方法が 1 つありますselect。この呼び出しには、タイムアウトを設定できる 5 番目の引数があります。それを(誤用して)、決して起こらないことがわかっているネットワークイベントを待つことができ、制御された時間の後にタイムアウトします。その上のLinuxマニュアルから:

一部のコードではselect()、3 つすべてのセットを空、nfdsゼロ、NULLタイムアウトなしで呼び出して、1 秒未満の精度でスリープするかなり移植性の高い方法を使用しています。

于 2013-09-21T06:17:48.847 に答える