データ収集技術は、産業用制御やオートメーションなどの分野で重要な役割を果たしています。データ収集の一般的なプロセスは次のとおりです。
①チャネル選択コマンドをキャプチャカードに送信します。 ②収集したいチャンネル番号を選択します。 ③A/D変換を開始します。 ④変換が完了するまで待ちます。 ⑤取得カードからデータを読み取ります。マルチチャネル取得の場合、プログラム設計では通常 2 つの方法が使用されます。クエリメソッドまたは割り込みメソッド。いわゆるクエリ方式では、ループを使用して各データ チャネルを順番に収集します。クエリ方式の利点は、プログラムがシンプルで実装が簡単であることです。欠点は、収集プロセス中に CPU がほとんどの時間を待機に費やし、リソースが無駄になることです。割り込み方式はハードウェア割り込み方式を採用しており、まずA/D変換を開始し、変換終了時に割り込み信号を送信し、収集カードのデータ割り込みに応答してCPUが収集データを読み出します。このようにして、変換を待機している間、CPU は待機状態になることなく他の計算を実行できます。割り込み方式の利点は、リソースを最大限に活用できることですが、特にシステムのハードウェア割り込みリソースが不足している場合、プログラムの設計が複雑になるため、Windows や Windows などのオペレーティング システムでは割り込みの競合が発生しやすくなります。 Win95 では、ユーザーは割り込みハンドラー時間をインストールすることを許可されていないため、これを達成することはできません。
---- 上で説明した 2 つの方法はどちらも DOS での方法ですが、Win95 では、より優れた方法であるマルチスレッド テクノロジが存在します。データ収集にマルチスレッド テクノロジーを利用できるようになりました。
---- 1. データ収集にマルチスレッドを使用する利点
---- Win95/98 で最も人気があるのは、美しいインターフェイスのほかに、マルチスレッドとマルチタスクです。 DOS 環境では、実行プログラムがすべてのリソースを独占できますが、Windows 環境では、やや初歩的なマルチタスク環境ではありますが、プログラムは希望に応じてすべての CPU 時間を制御できます。ただし、Windows95 や Windows NT では、プログラムがすべての CPU 実行時間を独占することはできません。また、プログラムは最初から最後まで一行ではありません。逆に、プログラムを実行中に複数のプログラム断片に分割し、同時に実行することもできます。同時に実行できるこれらのプログラムの断片はスレッドと呼ばれます。 Windows 95 および Windows NT では、オペレーティング システムは複数のプログラムを同時に交互に実行できます。これはマルチタスクです。
---- データ収集にマルチスレッドを使用すると、プログラムの応答速度が効果的に高速化され、実行効率が向上します。一般的なプログラムはユーザーの入力を処理する必要がありますが、CPUの実行速度に比べれば、ユーザーの入力速度は歩いたり飛んだりするような速度です。このように、CPU は (DOS 環境などで) ユーザー入力を待つために多くの時間を無駄にします。マルチスレッドを使用する場合、1 つのスレッドをユーザー入力の待機に使用でき、もう 1 つのスレッドはデータ処理またはその他の作業を実行できます。データ収集プログラムの場合、データ収集に別のスレッドを使用できます。このようにして、収集のリアルタイム性を最大限に保証しながら、他のスレッドがユーザー操作に応答したり、タイムリーにデータ処理を実行したりできます。そうしないと、プログラムはデータを収集するときにユーザーの操作に応答できなくなり、ユーザーの操作に応答するときにデータを収集できなくなります。特に、収集されるデータの量が多く、データ処理タスクが重い場合、マルチスレッドを使用しない場合、収集中の長時間の待機は十分に許容されます。
---- ただし、マルチスレッドは通常のプログラミングよりもはるかに複雑です。複数のスレッドがいつでも同時に実行される可能性があるため、多くの変数やデータが他のスレッドによって変更される可能性があります。これは、マルチスレッド プログラムにおけるスレッド間の同期制御の最も重要な問題です。
---- 2. データ収集のマルチスレッド化で解決すべき課題
---- 実際、マルチスレッド プログラミングの複雑さは一時的なものであり、マルチスレッド設計に従来の C を使用する場合は、スレッド間の同期を自分で制御する必要があります。それは複雑でしょう。ただし、オブジェクト指向設計手法を使用し、マルチスレッド プログラミングに Delphi を使用する場合、問題ははるかに単純になります。これは、Delphi がマルチスレッドの複雑さを処理してくれており、私たちがしなければならないのは継承だけだからです。
---- 具体的には、マルチスレッドのデータ収集では次の作業を完了する必要があります。
---- ① TThreadクラスから独自クラスSampleThreadを派生します。これはデータ収集に使用するクラスです。収集するときは、SampleThread のインスタンスを作成するだけです。
---- ② スーパークラス TThread の Execute メソッドをオーバーロードします。この方法では、データ収集タスクが具体的に実行されます。
---- ③収集と表示を同時に行いたい場合は、Executeメソッドで呼び出す収集進捗表示処理を複数記述します。
----TThread クラスで最も一般的に使用される属性/メソッドは次のとおりです。
メソッドの作成: コンストラクター Create
(CreateSuspended: ブール値);
----CreateSuspended パラメータは、スレッドが作成されたときにすぐに実行されるかどうかを決定します。 True の場合、新しいスレッドは作成後に一時停止されます。False の場合、スレッドは作成直後に実行されます。
FreeOnTerminate プロパティ:
PROperty FreeOnTerminate: ブール値;
---- この属性は、プログラマがこのスレッドをキャンセルする責任があるかどうかを決定します。このプロパティが True の場合、VCL はスレッドの終了時にスレッド オブジェクトを自動的に破棄します。デフォルト値は False です。
OnTerminate プロパティ:
プロパティ OnTerminate: TNotifyEvent;
---- この属性は、スレッドの終了時に発生するイベントを指定します。
---- 具体的な例を見てみましょう。
---- 3. マルチスレッドデータ収集の実装
---- これはポンプユニットの性能図を測定するために著者が開発したプログラムです。その機能は、ポンプユニットの吊り点の荷重と変位データを収集し、処理後のポンプユニットの動作図を作成することです。データ収集時のインターフェースを図1(省略)に示します。 「データの収集」ボタンをクリックすると、プログラムは新しいスレッドを作成し、そのプロパティを設定します。この新しいスレッドによってデータ収集タスクが完了します。手順は次のとおりです。
プロシージャサンプルフォーム。
DoSampleBtnClick(送信者: TObject);
始める
ReDrawBtn.Enabled := True;
DoSampleBtn.Enabled := False;
FFTBtn.Enabled := True;
TheSampler := SampleThread.Create(False);
収集スレッドを作成する
TheSampler.OnTerminate := FFTBtnClick;
収集完了後に実行するタスク
TheSampler.FreeOnTerminate := True;
収集完了後に元に戻す
終わり;
----収集スレッドのクラス定義は次のとおりです。
タイプ
サンプルスレッド = クラス(TThread)
公共
関数 AdRead(ach: バイト): 整数;
A/Dカード読み取り機能
プロシージャUpdateCaption;
収集時間を表示する
プライベート
{プライベート宣言}
保護された
thes、thep: 本物。
dt: 実数。
ID: 整数;
st、編集: LongInt;
プロシージャをオーバーライドします。
これが鍵です。
終わり;
---- このクラスでは、A/D カードを操作するための関数 AdRead が定義されており、収集の進行状況と時間を表示するために 2 つのプロセスが使用されます。 AdRead 関数はアセンブリで記述されており、パラメーターの呼び出し形式はセーフコールである必要があることに注意してください。
----キーのオーバーロードされたメソッド Execute のコードは次のとおりです。
プロシージャ SampleThread.Execute;
始める
StartTicker := GetTickCount;
ID := 0;
繰り返す
thes := Adread(15) * ad2mv * mv2l;
チャンネル15を取得
thep := Adread(3) * ad2mv * mv2n;
チャンネル3を取得
dt := GetTickCount - StartTicker;
sarray[id] := thes;
parray[id] := thep;
tarray[id] := dt;
inc(id);
同期(UpdateCaption);
注: 収集の進行状況を表示します
ID >=4096まで;
ed := GetTickCount;
同期(ShowCostTime);
注: 費やした時間を表示します
終わり;
---- 上記のコードからわかるように、Execute コードと通常のコードの間に本質的な違いはありません。唯一の違いは、収集の進行状況を表示するときと経過時間を表示するときに、それぞれのプロシージャを直接呼び出すことはできず、Synchronize を呼び出すことで間接的に呼び出すことができることです。これは、プロセス間の同期を維持するために行われます。
---- 4. 結論
----上記のプログラムは Delphi 4.0 を使用してプログラムされ、AMD-K6-2/300 に実装されています。テスト結果は次のとおりです。マルチスレッドを使用すると、4096 ポイントを収集するのに通常 10 ~ 14 秒かかります。マルチスレッドを使用しない場合は、1 分から 1 分半かかります。マルチスレッドによってプログラムの実行効率が大幅に向上することがわかります。