Delphiのスレッドクラス
ラプター[メンタルスタジオ]
http://mental.mentsu.com
三番目
コンストラクターについて話した後、デストラクターを見てみましょう。
デストラクター TThread.Destroy;
始める
(FThreadID <> 0) かつ FFinished ではない場合
始める
終了します。
FCreateSuspended の場合
再開する;
待ってください。
終わり;
if FHandle <> 0 then CloseHandle(FHandle);
継承された破壊。
FFatalException.Free;
スレッドを削除します。
終わり;
スレッド オブジェクトを解放する前に、まずスレッドがまだ実行中かどうかを確認します。スレッドがまだ実行中の場合 (スレッド ID が 0 ではなく、スレッド終了フラグが設定されていない場合)、スレッドを終了するために Terminate プロセスが呼び出されます。 Terminate プロセスは、次のコードのように、スレッド クラスの Terminated フラグを設定するだけです。
プロシージャ TThread.Terminate;
始める
F終了 := True;
終わり;
したがって、スレッドはすぐに終了するのではなく、正常に終了するまで実行を継続する必要があることに注意してください。
ここで少し脱線します。多くの人が、スレッドを「すぐに」終了する方法を私に尋ねてきました (もちろん、TThread で作成されたスレッドのことです)。もちろんうまくいきません!スレッドを終了する唯一の方法は、Execute メソッドの実行を完了させることです。したがって、一般的に言えば、スレッドをできるだけ早く終了させたい場合は、短時間内に Execute メソッドの Terminated フラグを常にチェックする必要があります。時間内に退出できること。これは、スレッド コードを設計する際に非常に重要な原則です。
もちろん、スレッドを「すぐに」終了できる必要がある場合、TThread クラスは良い選択ではありません。API を使用してスレッドを強制的に終了すると、最終的に TThread スレッド オブジェクトが正しく解放されなくなるためです。オブジェクトが破棄されるとアクセス違反が発生します。この場合、スレッドの作成には API 関数または RTL 関数のみを使用できます。
スレッドが起動一時停止状態にある場合は、スレッドを実行状態に移行してから、WaitFor を呼び出して、スレッドが終了するまで待機してから実行を続行します。 WaitForの実装については後述します。
スレッドが終了したら、スレッド ハンドル (ハンドルは通常のスレッド作成時に存在します) を閉じ、オペレーティング システムによって作成されたスレッド オブジェクトを解放します。
次に、TObject.Destroy を呼び出してこのオブジェクトを解放し、キャッチされた例外オブジェクトを解放します。最後に RemoveThread を呼び出して、プロセス内のスレッドの数を減らします。
一時停止/再開およびスレッドの優先順位設定に関するその他の側面については、この記事の焦点ではないため、再度説明しません。以下で説明するのは、この記事の他の 2 つの焦点である Synchronize と WaitFor です。
ただし、これら 2 つの関数を導入する前に、イベントとクリティカル セクションという他の 2 つのスレッド同期テクノロジを導入する必要があります。
イベントはデルフィのイベントとは異なります。本質的に、Event はグローバル ブール変数と同等です。 Set と Reset という 2 つの代入操作があり、これは True または False に設定するのと同じです。そして、その値のチェックは WaitFor 操作を通じて行われます。 Windows プラットフォームに対応して、SetEvent、ResetEvent、および WaitForSingleObject の 3 つの API 関数があります (WaitFor 関数を実装する API はいくつかありますが、これが最も単純なものです)。
これら 3 つはプリミティブであるため、Event は、一般的なブール変数ではできないアプリケーションをマルチスレッドで実装できます。 Set と Reset の機能についてはすでに説明しました。次に、WaitFor の機能について説明します。
WaitFor の機能は、イベントの状態が Set 状態 (True と同等) であるかどうかを確認することです。そうであれば、待機期間中に Set 状態に変わるまで待機します。 WaitFor を呼び出しているスレッドは一時停止状態です。また、WaitFor にはタイムアウト設定のパラメータがあり、このパラメータが 0 の場合は待機せず、INFINITE の場合は Set ステータスが発生するまで無限に待機します。対応するミリ秒間待機し、イベントのステータスを返します。
イベントが Reset 状態から Set 状態に遷移すると、WaitFor イベントによって中断されていた他のスレッドが起動されるため、イベントと呼ばれます。いわゆる「イベント」とは「状態遷移」を指します。この「状態遷移」情報は、イベントを通じてスレッド間で受け渡すことができます。
もちろん、WaitFor がブール値をチェックするコードのループに置き換えられる限り、保護された (以下の重要なセクションの紹介を参照) ブール変数を使用して同様の機能を実現することもできます。機能的には全く問題ありませんが、実際に使用してみると、このような待機は多くの CPU リソースを占有し、システムのパフォーマンスが低下し、他のスレッドの実行速度に影響を与えるため、不経済であり、場合によっては発生する可能性もあります。問題。したがって、この方法で使用することはお勧めできません。
(つづく)