この記事で扱っていること
- 指定した時間にプログラムを実行する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
プログラムを書く為の目的の一つは、何か特定の処理を機械的、自動的に行わせることにあると思います。
あるプログラムを書いて、これを実行し目的の動作を自動的に行わせることができたとします。
次に気にすることの一つとしては、その実行するという操作自体もある程度自動化させる、ということが挙げられると思います。
つまり、あらかじめ定めておいた時間に従って指定したプログラムを実行するようなプログラムを書いておけば、そのスケジュール通りに処理をさせることができます。
この記事では、そんなプログラム実行をスケジュール通りにさせるためのプログラムの例について紹介しています。
どんな結果になるか
スケジュール通りにプログラムを実行させるために、時間を指定するタイムスタンプと、実行させるプログラムのファイルパスを指定します。
実行したい時間を複数、配列に指定して実行すれば、VIパスに指定したプログラムが指定した時間に実行されるようになります。
ただし、
- 呼び出されるプログラムは処理後に自分自身で終わるような形になっている(あるいはユーザーの操作によって終わらせることができる)
- 実行されたプログラムが、次の予定時間になるまでに終わる(終わらないとスケジュールがずれる)
という注意点があります。
プログラムの構造
中身としては単純で、指定した時間を経過したかどうかをWhileループで判断し、経過したらプログラムを実行するだけ、です。
時間配列の中身はユーザーが上から順に現在から近い時間を入力してくれる、とも限らないので、適切にソートする処理を入れています。
時間が経過したかどうかについては、タイムスタンプデータを浮動小数点データに変換したうえで大小を比べています。
なお、上のプログラム例はキューを使用した生産者消費者デザインをベースにしていますが、これは後で紹介するプログラムへの応用も考えています。
生産者ループではひたすら現在の時間を確認し、設定した時間を過ぎたらプログラムを実行する命令を消費者ループに与えます。
生産者ループの方は特に待機関数など設けていませんが、なるべく指定した時間通りに実行させたいということでもなければ、待機関数を使用した方が余計にループを回さない分CPUの負荷は減ります。
消費者ループでは生産者ループからの命令に従ってプログラムを実行します。
この部分に、実行するviのアイコンを直接配置することもできますが、それだと異なるプログラムを呼び出す場合にブロックダイアグラムを編集する必要があるため、VIのリファレンスを開いて実行するようにしています。
消費者ループにあたる部分では、同期呼び出しではなく非同期呼び出しにすれば同じプログラムを複数のインスタンス呼び出すことが可能になると思いますが、ここでは扱っていません。
異なるプログラムを指定する場合
時間ごとに異なるプログラムを指定する場合には、それぞれのタイムスタンプごとに実行するプログラムの時間を指定する必要があります。
時間とプログラムがセットになるので、これらをクラスタとし、このクラスタの配列を扱うようにします。
実装の一例としては以下の通りで、キューによってプログラムのパスの情報を消費者ループに渡してやります。
「時間とファイルパスのクラスタ」の配列から、時間の情報だけ取り出してソートし、指定した時間が過ぎたら、その指定時間をもともと持っていた「時間とファイルパスのクラスタ」の配列要素を時間情報の一致によって特定し、その要素のファイルパスをキューで渡しています。
なお、こちらのプログラムでは、生産者ループが終わってからキューの要素がなくなるまで待機する処理を設けています。
この処理が無くても、各時間に実行するプログラムが次の指定した時間までに十分早く終わるのであれば問題ないと思いますが、思ったより時間がかかってなおかつ時間の指定が詰まっているとキューにたまったプログラムが実行されない状態はあり得るので、それを避けるための仕組みです。
実行させる時間間隔が決まっている場合
時間間隔が初めから決まっている場合には、最初の時間だけ指定してその時間間隔および何回繰り返すかの2つのパラメタを追加すれば対応できます。
時間情報を持った配列を用意すればよく、以下のような実装が考えられます。
(ケースストラクチャのFalseケースはこれまでに紹介したものと同じなので図を省いています)
実行させるごとに一部のパラメタを変更する場合
同じプログラムを実行させるにしても、そのプログラムの一部のパラメタを毎回異なる値にしたい、という場面もあると思います。
そんなときには、「時間とそのときのパラメタのクラスタ」を扱うことで対応できます。
例えば、下の図の右下に書いたプログラムを呼び出すという場合を考えます。
インボークノードを使用して制御器の値を設定すれば、毎回異なる値を渡せます。
以下は、値の設定を、呼び出すプログラムの二つの制御器(上の図の例だと「wait」と「number」)に対して行った場合の例です。
インボークノードの制御器の値設定では、制御器の名前とそこに与える値をともに指定することになります。
本記事では、指定した時間にプログラムを実行させる方法について紹介しました。
定期的に動かすプログラムがある場合に、タイムスタンプで時間を指定するようにしてなるべく多くのことを自動的に処理できるようにしたい、と思ったときに参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント