8

私は自分の仕事のためにRubyでジョブスケジューリングアプリを書いています(主に特定の頻度でさまざまなプロトコルを使用してファイルを移動するため)

私のメインループは次のようになります:

while true do
  # some code to launch the proper job
  sleep CONFIG["interval"]
end

それは魅力のように機能していますが、アプリケーションがCPUを集中的に使用するソフトウェアを実行しているサーバーで実行される可能性があるため、十分に安全かどうかはわかりません。

同じことをする別の方法はありますか、それともsleep()私の場合は十分に安全ですか?

4

5 に答える 5

7

ブロックする必要があると感じたときはいつでも、イベント ループを使用します。通常はlibev。以下は Ruby バインディングです。

http://rev.rubyforge.org/rdoc/

基本的にsleep、バックグラウンドで他に何も実行せずにプロセスをスリープ状態にしたい場合は、まったく問題ありません。ただし、スリープなどの他のことを行い、TCP 接続またはファイルハンドルが読み取り可能になるまで待機する場合は、イベント ループを使用する必要があります。では、最初に 1 つだけ使用してみませんか?

お申し込みの流れは次のとおりです。

main {
   Timer->new( after => 0, every => 60 seconds, run => { <do your work> } )
   loop();
}

他のことをしたい場合は、ウォッチャーを作成するだけで、それが自動的に行われます。(実行中のジョブもウォッチャーを作成できます。)

于 2009-07-24T18:26:52.450 に答える
6

スリープの使用は、迅速で汚いものにはおそらく問題ありません。しかし、もう少し堅牢性や信頼性が必要なものについては、スリープは悪であることをお勧めします:) スリープの問題は、スレッド(ここではWindowsを想定しています...)が本当にスリープしていることです-スケジューラはスレッドを実行しませんスリープ間隔が経過した後しばらくするまで。

この間、スレッドは何も起きません。これは、キャンセルできないこと、またはある種のイベントを処理するために起動できないことを意味します。もちろん、プロセスを強制終了することはできますが、それではスリープ状態のスレッドが起動して何かをクリーンアップする機会が与えられません。

Ruby には詳しくありませんが、Ruby には複数のことを待機するための何らかの機能があると思います。可能であれば、睡眠を使用する代わりに、2 つのことを待つことをお勧めします\

  1. スレッドを定期的に起動して作業を行うタイマー。
  2. プロセスがキャンセルまたは終了する必要があるときに設定されるイベント (たとえば、control-C をトラップする)。

仕事をする必要があることを知らせるために使用できる何らかのイベントがあれば、さらに良いでしょう。これにより、タイマーでのポーリングが回避されます。これにより、通常、リソースの使用率が低下し、システムの応答性が向上します。

于 2009-07-24T18:38:57.307 に答える
3

正確な間隔が必要ない場合は、私には理にかなっています。ドリフトせずに定期的に目覚める必要がある場合は、何らかの外部タイマーを使用することをお勧めします。しかし、眠っているときは、CPUリソースを使用していません。高価なのはタスクスイッチです。

于 2009-07-24T18:23:37.900 に答える
2

スリープ中に CPU を使用することはありませんが、長時間スリープしている場合は、実行中の Ruby インタープリターが何もしていないときにメモリを保持することがより懸念されます。これはそれほど大したことではありません。

于 2009-07-24T18:29:46.157 に答える