2010/09/21

プロセスのCPU使用率を監視して自動処理

先日の更新で、CPUの使用状況などを取得するためのクラスを提供する「SystemMonitor」ユニットが追加されました。
このユニットには、「CPU」、「ProcessCPU」、「Network」、「PerformanceCounter」の4つのクラスが用意されています。
「CPU」クラスでは、システム全体のCPU使用率が取得できます。マルチプロセッサの個別の稼働状況も取得可能です。
「ProcessCPU」クラスでは、指定のプロセスのCPU使用率を取得できます。
「Network」は、ネットワークインターフェイスの転送量を取得するクラスです。複数のネットワークインターフェイスの個別の転送量も取得できます。
他にも、「PerformanceCounter」を使うことで、HDDの読み書き量など様々な情報を取得できます。
また、標準クラスである「System」には「memory」メンバとしてシステムのメモリ使用状況を取得するメンバが追加された他、以前からProcessインスタンスの「pagefileUsage」プロパティや「workingSetSize」プロパティでプロセスごとのメモリ使用状況を取得可能になっています。

これらの機能は、タスクマネージャのような情報表示だけでなく、自動処理を進める条件などとしても役立つでしょう。
例えば、動画のエンコードなどの時間のかかる処理が終ってから別の処理を自動実行させたいけれどエンコードソフトがプロセスの存続やウィンドウのテキストなどによる終了判定がしにくい仕様になっている場合に、プロセスのCPU使用率が低くなった時点で処理完了とみなすといった具合です。

このような場合、以下の例のようなスクリプトで、処理の完了まで待機させることが出来ます。
var p=Process.find("VirtualDub.exe");
try{
    var mon=new (require('SystemMonitor').ProcessCPU)(p);
    sleep(1000);
    while(mon.get()>0.05){
        sleep(1000);
    }
}finally{
    free(mon);
}
sleep(10000);
//以降にエンコード終了後の処理を記述

最初の行で、監視対象となるProcessオブジェクトを取得しています。
この例では、既に実行中のプロセスを取得する「Process.find()」を使っていますが、「Process.create()」でプロセスの起動から自動化してもよいでしょう。
「var mon=new (require('SystemMonitor').ProcessCPU)(p);」で、そのプロセスのCPU使用率を取得するためのProcessCPUオブジェクトを生成しています。
プロセスのCPU使用率を取得するには、このオブジェクトの「get()」メソッドを呼び出します。
このメソッドは、前回呼び出し時かインスタンス生成時から今回呼び出し時までの期間のCPU使用率を返すので、インスタンス後に即座に呼び出してしまうと正常な値が取得できないため、最初のget()呼び出しの前にもsleep()が呼び出されるようにしておく必要があります。
get()の返り値は0~1の間の小数となるので、上記の例ではCPU使用率が5%以下になるまでループし続けることになります。
CPU使用率が低くなった直後は、まだファイルへの書き込みなどの処理が行われている可能性があるので、数秒程度sleep()してから次の処理に進むようにするとよいでしょう。
なお、「free(mon)」は、監視オブジェクトで使用したリソースを解放するための処理ですが、一連の処理を実行してすぐに終了するタイプのスクリプトでは、省略しても問題は無いでしょう。

なお、CPUやNetwork、PerformanceCounterクラスも、インスタンスを生成してget()で値を取得するという流れはProcessCPUと同じです。
コンストラクタに渡す引数やget()が返す内容などの詳しい仕様は、同梱のdoc\SystemMonitor.txtを参照してください。

0 件のコメント:

コメントを投稿