プロセスとワーカー
4D のマルチタスク機能は、複数の処理を同時に実行することを可能にします。 これらの処理を プロセス と呼びます。 マルチプロセスは、1つのコンピューター上でのマルチユーザーのようなもので、それぞれの処理は個別のタスクです。 つまり、それぞれのメソッドを個別のデータベースタスクとして実行できるということです。
コードがスレッドセーフであれば プリエンプティブプロセス を作成できるため、コンパイル済みアプリケーションをマルチコアコンピューターで実行することで、処理がより高速になります。
4Dアプリケーションは自身が必要とするプロセスも作成します。例: ユーザインタフェースのウィンドウ表示を管理するメインプロセス、デザインモードのウィンドウとエディターを管理するデザインプロセス (これらはワーカープロセスです)、Webサーバープロセス、キャッシュマネージャープロセス、インデックスプロセス、そして On Event Managerプロセス。
プロセスの作成とクリア
新規プロセスを作成するにはいくつかの方法があります:
- デザインモードにおいて、"メソッド実行" ダイアログボックスで 新規プロセス チェックボックスをチェックした後、メソッドを実行する。 メソッド実行ダイアログボックスで選択したメソッドが (そのプロセスをコントロールする) プロセスメソッドとなります。
New process
コマンドを使用する。New process
コマンドの引数として渡されたメソッドがプロセスメソッドです。Execute on server
コマンドを使用して、サーバー上にストアドプロシージャーを作成する。 コマンドの引数として渡されたメソッドがプロセスメソッドです。CALL WORKER
コマンドを使用する。 ワーカープロセスが既に存在していない場合、新たに作成されます。
デスクトップアプリケーションでは、メニューコマンドを選択することでプロセスを開始できます。 メニューエディター
において、メニューコマンドを選択して、新規プロセスで開始 チェックボックスをクリックします。 メニューコマンドに関連付けられたメソッドがプロセスメソッドです。
プロセスは以下の条件でクリアできます。最初の 2つの条件では自動的におこなわれます:
- プロセスメソッドの実行が完了したとき。
- ユーザーがアプリケーションを終了したとき。
- メソッドからプロセスを中止するか、またはデバッガーまたはランタイムエクスプローラーで アボート ボタンを使用した場合。
KILL WORKER
コマンドを呼び出した場合 (ただしワーカープロセスを削除する場合のみ)。
プロセスは別のプロセスを作成することができます。 プロセスは階層構造にはなっていません。どのプロセスから作成されようと、すべてのプロセスは同等です。 いったん、“親” プロセスが “子” プロセスを作成すると、親プロセスの実行状況に関係なく、子プロセスは処理を続行します。
プロセスの要素
各プロセスには、他のプロセスから独立して扱えるいくつかの要素があります。
ランゲージ要素
- 変数: すべてのプロセスは独自の
プロセス変数
を持っています。 プロセス変数はその変数を作成したプロセスの範囲内でのみ認識されます。 - プロセスセット: 各プロセスは、独自のプロセスセットを持っています。
LockedSet
はプロセスセットです。 プロセスセットは、プロセスメソッドが終了すると直ちに消去されます。 エラー処理メソッド
: 各プロセスは、独自のエラー処理メソッドを持てます。デバッガーウィンドウ
: 各プロセスは、独自のデバッガーウィンドウを持つことができます。
インタフェース要素
インターフェース要素は、デスクトップアプリケーション で使用されます。 以下のものがあります:
- メニューバー: 各プロセスは、独自のカレントメニューバーを持つことができます。 最前面のプロセスのメニューバーがアプリケーションのカレントメニューバーになります。
- 1つ以上のウィンドウ: 各プロセスは、1つまたは複数のウィンドウを同時に開くことができます。 他方、ウィンドウをまったく持たないプロセスもあります。
- 1つのアクティブ (最前面) ウィンドウ: プロセスは、複数のウィンドウを同時に開くことができますが、アクティブウィンドウは各プロセスに1つしかありません。 複数のアクティブウィンドウを持つには、アクティブウィンドウの数だけプロセスを起動しなければなりません。
- 入力フォームと出力フォーム: 各プロセスの各テーブルに対して、デフォルトの入力フォームと出力フォームをメソッドから設定することができます。
- プロセスはデフォルトではメニューバーを含みません。つまり、編集 メニューのショートカット (具体的には、カット/コピー/ペースト) はプロセスウィンドウでは利用できません。 プロセスからダイアログボックスや 4Dエディター (フォームエディター、クエリエディター、Request等) を呼び出した場合、 ユーザーがコピー/ペーストなどのショートカットを利用できるようにするためには、編集 メニューに相当するものがプロセスにインストールしておく必要があります。
- プリエンプティブプロセス と、サーバー上で実行されるプロセス (ストアドプロシージャー) にインターフェース要素を含めてはいけません。
各プロセスは、テーブルごとのカレントセレクションおよびカレントレコードも持ちます。 これらのコンセプトの詳細については、doc.4d.com を参照ください。
グローバルプロセスとローカルプロセス
プロセスのスコープにはローカルとグローバルがあります。 デフォルトですべてのプロセスはグローバルです。
グローバルプロセスはデータへのアクセスや操作を含め、あらゆる処理を実行できます。 ほとんどの場合、グローバルプロセスを使用します。 ローカルプロセスは、データアクセスを必要としない処理の場合にだけ使用することをお勧めします。 たとえば、イベント処理メソッドの実行や、フローティングウィンドウ等のインターフェース要素を制御するためにローカルプロセスを使用します。
名前によってプロセスのスコープがローカルであることを指定します。 ローカルプロセス名は、先頭にドル記号 ($) を付ける必要があります。
ローカルプロセスでデータアクセスをおこなった場合、メインプロセス (プロセス #1) でアクセスすることになり、そのプロセス内で実行される処理との間でコンフリクトが起きるおそれがあります。
4D Server
データアクセスをおこなわない処理に対し、クライアント側でローカルプロセスを使用すると、サーバーの負荷が軽減されます。 クライアント上でローカルなプロセスを作成した場合 (たとえば New process
を使用した場合など)、そのプロセスはクライアント上にしか存在しません。
クライアント上でグローバルなプロセスを作成した場合、その対となる "双子" プロセスがサーバー上で作成されるため、データアクセスとデータベースコンテキストを管理するためにサーバー側のリソースを消費します。 しかしながら、最適化の観点から、この双子プロセスは必要がある場合 (たとえばグローバルプロセスがデータに最初にアクセスするときなど) にのみ作成されます。
ワーカープロセス
ワーカープロセスとは、簡単かつ強力なプロセス間通信の方法です。 この機能は非同期のメッセージシステムに基づいており、プロセスやフォームを呼び出して、呼び出し先のコンテキストにおいて任意のメソッドを指定パラメーターとともに実行させることができます。
あらゆるプロセスは CALL WORKER
コマンドを使用することでワーカープロセスを "雇用" することができ、ワーカーのコンテキストにおいて任意のプロジェクトメソッドを指定のパラメーターで実行させることができます。つまり、呼び出し元のプロセスとワーカーの間で情報の共有が可能です。
デスクトップアプリケーションにおいては、CALL FORM
コマンドを使うことで、あらゆるフォームのコンテキストにおいて任意のプロジェクトメソッドを指定のパラメーターで実行させることができます。
これらの機能は、4D のプロセス間通信における次のニーズに対応します:
- コオペラティブおよびプリエンプティブプロセスの両方に対応しているため、インタープロセス変数が使えないプリエンプティブプロセスにおけるプロセス間通信に最適です (インタープロセス変数は現在、非推奨です)。
- 煩雑になりやすいセマフォーの代替手法として使用できます。
CALL WORKER
および CALL FORM
のコマンドは、主にプリエンプティブプロセスのコンテキストにおけるプロセス間通信のために開発されましたが、コオペラティブプロセスにおいても同様に使用することができます。
ワーカーの使用
ワーカーは、プロジェクトメソッドの実行を別プロセスに依頼するときに使います。 ワーカーには次のものが付随します:
- ワーカーを特定する一意の名称 (警告: ワーカー名は文字の大小を区別します)。これは、関連プロセスの名称にも使われます。
- ワーカーに関連付けられたプロセス (特定の時点において存在しない場合もあります)
- メッセージボックス
- 初期メソッド (任意)
CALL WORKER
コマンドを使って、プロジェクトメソッドの実行をワーカーに依頼します。 初めてワーカーを使用するときに、ワーカーはメッセージボックスとともに生成され、依頼内容を関連プロセスにて実行します。 ワーカープロセスが終了してもメッセージボックスは開いたままで、次のメッセージを受け取るとワーカープロセスが再開します。
この一連の流れをアニメーションで表しました:
New process
コマンドで作成されるプロセスとは異なり、ワーカープロセスは プロセスメソッドの実行終了後も生きています。 つまり、特定のワーカーにおけるメソッド実行はすべて同一プロセス内でおこなわれ、すべてのプロセス情報 (プロセス変数、カレントレコード、カレントセレクション、など) が保持されます。 続けて実行されるメソッドはこれらの情報を共有することになるため、プロセス間の通信が可能になります。 ワーカーのメッセージボックスは連続した呼び出しを非同期的に扱います。
CALL WORKER
はメソッド名と引数をカプセル化し、メッセージとしてワーカーに受け渡します。 ワーカープロセスは、存在していなければ生成され、メッセージボックスに格納されたメッセージを実行します。 したがって、大体の場合において CALL WORKER
は、受け取ったメソッドをワーカーが実行するより先に終了します (非同期的な処理)。 そのため CALL WORKER
は戻り値を返しません。 実行後の情報をワーカーから返してもらうには、'CALL WORKER' を利用してワーカーの呼び出し元に情報を返す必要があります (コールバック)。 つまり、この場合には、呼び出し元のプロセスもワーカーである必要があります。
New process
コマンドで作成されたプロセスを、CALL WORKER
で呼び出して、ワーカーとして使うことはできません。 メッセージボックスを持つワーカープロセスのみが、CALL WORKER
によって呼び出し可能です。 New process
で作成されたプロセスがワーカーをコールすることは可能でも、ワーカーからのコールバックは受けられないことに留意が必要です。
ワーカープロセスは、ストアドプロシージャーを使って 4D Server 上に作成することもできます。たとえば、CALL WORKER
コマンドを実行するメソッドを Execute on server
コマンドから実行できます。
ワーカープロセスを閉じるには KILL WORKER
コマンドをコールします。これによってワーカーのメッセージボックスが空にされ、関連プロセスはメッセージの処理を停止し、現在のタスク完了後に実行を終了します。
ワーカープロセスを新規生成する際に指定したメソッドがワーカーの初期メソッドになります。 次回以降の呼び出しで method パラメーターに空の文字列を受け渡した場合、CALL WORKER
はこの初期メソッドの実行をワーカーに依頼します。
ユーザーおよびアプリケーションモードで 4Dデータベースを開く際に作成されるメインプロセスはワーカーです。したがって、CALL WORKER
で呼び出すことができます。 メインプロセスの名称は 4D の使用言語により異なりますが、プロセス番号は常に 1 です。CALL WORKER
でメインプロセスを呼び出す場合には、プロセス番号を使うのが便利でしょう。
ワーカープロセスの識別
PROCESS PROPERTIES
コマンドを使った場合、メインプロセス以外のすべてのワーカープロセスは Worker process
(5) をプロセスの種別として返します。
専用アイコン からもワーカープロセスを識別することができます。
参照
ワーカーの使い方の詳細については、このブログ記事 を参照ください。