8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DelphiAdvent Calendar 2021

Day 6

<0> はじめに (Delphi コンカレントプログラミング)

Last updated at Posted at 2021-12-05

0. はじめに

一連の記事では Delphi におけるコンカレント (並行) プログラミングを扱います。

日本語 英語 目的
並行計算 Concurrent Computing 応答性の向上
並列計算 Parallel Computing スループットの向上

並行計算並列計算 は似ている概念ですが、ちょっと意味合いが異なります。

See also:

0.1. 並行処理

並行処理を行うにはいくつかの方法があります。

0.1.1. プロセスとスレッド

プロセスとは簡単に言えば実行中のプログラムです。プログラムのインスタンスとも言えます。

スレッドとはプログラム内の処理の基本単位です。プロセスには必ず一つはスレッドがあり、メインスレッド (プライマリスレッド) と呼ばれます。並行処理のために追加されるスレッドはバックグラウンドスレッド と呼ばれます。

メインスレッドでないスレッドの事をワーカースレッドと呼ぶ事があるのですが、混乱を避けるため、当記事では次のような意味で使っています。

スレッド 呼称
アプリケーションの主スレッド メインスレッド
作成された副スレッド バックグラウンドスレッド
バックグラウンドスレッドのうち、
スレッドプールで管理されているスレッド
ワーカースレッド
現在実行中のスレッド カレントスレッド

以前の Windows (Microsoft) のマルチスレッド関係のドキュメントでは、

スレッド 呼称
アプリケーションの主スレッド
(メインスレッド)
プライマリスレッド
GUI を操作するスレッド
(バックグラウンドスレッド)
GUI スレッド
GUI を操作しないスレッド
(バックグラウンドスレッド)
ワーカースレッド

このような使われ方になっていたように思うのですが、現在の Microsoft のドキュメントでは ワーカースレッド という呼び方はスレッドプール (後述) に対してしか使われていない気がします (または Windows API のドキュメントの中)。

  • フォアグラウンドスレッドとバックグラウンドスレッドがある
  • UI スレッド = メインスレッド、非 UI スレッド = サブスレッド (バックグラウンドスレッド)
  • バックグラウンドスレッドとは裏で動く終了しないスレッドの事

...のように、OS や言語、フレームワーク、ライブラリによって言っている事や指しているものが異なる事があるので注意してください。

0.1.2. タイマーによる並行処理

TTimer を使えば、疑似的な並行処理を行う事ができます。

See also:

0.1.3. マルチプロセスによる並行処理

別プログラム (常駐プログラム等) を作ってプロセス間通信を行えばマルチプロセスによる並行処理を行う事ができます。各プロセスのスレッドは別のメモリ空間で実行されるため、データ共有の仕組を考える必要があります。

古い Delphi の $(DELPHI)\DEMOS\Ipcdemos にはプロセス間通信のデモプログラムがあります。

image.png

クライアントプログラム上でのマウス操作をモニタプログラムで監視するものです。また、このサンプルでは RTL に先駆けて同期オブジェクト (TEvent / TMutex) も実装されていました。

0.1.4. マルチスレッドによる並行処理

マルチスレッドを使えば並行処理を行う事ができます。スレッドは同じメモリ空間で実行されるので、データ共有が比較的簡単に行えます。

並行処理としてマルチプロセスがあまり使われないのは、プロセス間通信のコストが高いからです。そもそもマルチスレッドはライトウエイトプロセス (Light-weight process) から出発しています。

この一連の記事では主にマルチスレッドを扱います。

0.2. Delphi とスレッド処理

Delphi にスレッドルーチンやクラスが初めて実装されたのは Delphi 2 です。Delphi 1 は Windows 3.1 をターゲットとしていたため、スレッド管理ルーチンやクラスは存在しませんでした。

0.2.1 BeginThread / EndThread

Delphi には BeginThread()EndThread() というスレッドルーチンがあります。初期のものは Windows API をごく薄くラップしたルーチンでした。

Delphi Windows API
System.BeginThread() CreateThread()
System.EndThread() ExitThread()

Delphi 2 での定義は次のようになっています。

system.pas
function BeginThread(SecurityAttributes: Pointer; StackSize: Integer; ThreadFunc: TThreadFunc;
  Parameter: Pointer; CreationFlags: Integer; var ThreadId: Integer): Integer;

procedure EndThread(ExitCode: Integer);

BeginThread()EndThread() は スレッド API を Delphi から安全に使うためのラッパールーチンであり、CreateThread() / ExitThread() を直接扱う事は推奨されていません。しかしながら、この 2 つのルーチンだけではスレッド処理を行う事はできず、結局は Windows API を併用しなければなりません。

Delphi Windows API
CloseHandle()
GetThreadPriority()
ResumeThread()
SetThreadPriority()
System.SysUtils.Sleep() Sleep()
SuspendThread()
TerminateThread()
WaitForMultipleObjects()
WaitForSingleObject()

最近の Delphi には Windows プラットフォーム以外で動作する BeginThread() / EndThread() が用意されています。

system.pas
{$IFDEF POSIX}
function BeginThread(Attribute: PThreadAttr; ThreadFunc: TThreadFunc;
                     Parameter: Pointer; var ThreadId: TThreadID): Integer;
{$ENDIF}

Windows 用とパラメータが異なるため、BeginThread()EndThread() ですらも、直接扱わない方がいいかと思います。

0.2.2 スレッド操作

スレッド操作を行うクラスについては次の記事以降で紹介します。

参考

索引

[ ↑ 目次へ ] [ → 1. スレッドオブジェクト ]

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?