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

New process コマンドで作成されるプロセスとは異なり、ワーカープロセスは プロセスメソッドの実行終了後も生きています。 つまり、特定のワーカーにおけるメソッド実行はすべて同一プロセス内でおこなわれ、すべてのプロセス情報 (プロセス変数、カレントレコード、カレントセレクション、など) が保持されます。 続けて実行されるメソッドはこれらの情報を共有することになるため、プロセス間の通信が可能になります。 ワーカーのメッセージボックスは連続した呼び出しを非同期的に扱います。
CALL WORKER はメソッド名と引数をカプセル化し、メッセージとしてワーカーのメッセージボックスに受け渡します。 ワーカープロセスは、存在していなければ生成され、メッセージボックスに格納されたメッセージを実行します。 したがって、大体の場合において CALL WORKER は、受け取ったメソッドをワーカーが実行するより先に終了します (非同期的な処理)。 このため、CALL WORKER は値を何も返しません。 実行後の情報をワーカーから返してもらうには、CALL WORKER を利用してワーカーの呼び出し元に情報を返す必要があります (コールバック)。 つまり、この場合には、呼び出し元のプロセスもワーカーである必要があります。 ワーカープロセスは、存在していなければ生成され、メッセージボックスに格納されたメッセージを実行します。 したがって、大体の場合において CALL WORKER は、受け取ったメソッドをワーカーが実行するより先に終了します (非同期的な処理)。 このため、CALL WORKER は値を何も返しません。 実行後の情報をワーカーから返してもらうには、CALL WORKER を利用してワーカーの呼び出し元に情報を返す必要があります (コールバック)。 つまり、この場合には、呼び出し元のプロセスもワーカーである必要があります。
CALL WORKER を使用して、New process コマンドで作成されたプロセス内においてメソッドを実行させることはできません。 メッセージボックスを持つワーカープロセスのみが、CALL WORKER によって呼び出し可能です。 New process で作成されたプロセスがワーカーをコールすることは可能でも、ワーカーからのコールバックは受けられないことに留意が必要です。 メッセージボックスを持つワーカープロセスのみが、CALL WORKER によって呼び出し可能です。 New process で作成されたプロセスがワーカーをコールすることは可能でも、ワーカーからのコールバックは受けられないことに留意が必要です。
ワーカープロセスは、ストアドプロシージャーを使って 4D Server 上に作成することもできます。たとえば、CALL WORKER コマンドを実行するメソッドを Execute on server コマンドから実行できます。
ワーカープロセスを閉じるには KILL WORKER コマンドをコールします。これによってワーカーのメッセージボックスが空にされ、関連プロセスはメッセージの処理を停止し、現在のタスク完了後に実行を終了します。
ワーカープロセスを新規生成する際に指定したメソッドがワーカーの初期メソッドになります。 ワーカープロセスを新規生成する際に指定したメソッドがワーカーの初期メソッドになります。 次回以降の呼び出しで method パラメーターに空の文字列を受け渡した場合、CALL WORKER はこの初期メソッドの実行をワーカーに依頼します。
ユーザーおよびアプリケーションモードで 4Dデータベースを開く際に作成されるメインプロセスはワーカーです。したがって、CALL WORKERで呼び出すことができます。 メインプロセスの名称は 4D の使用言語により異なりますが、プロセス番号は常に 1 です。CALL WORKER でメインプロセスを呼び出す場合には、プロセス番号を使うのが便利でしょう。 メインプロセスの名称は 4D の使用言語により異なりますが、プロセス番号は常に 1 です。CALL WORKER でメインプロセスを呼び出す場合には、プロセス番号を使うのが便利でしょう。
ワーカープロセスの識別
全てのワーカープロセス(メインプロセスを除く)は、Process info コマンドからは Worker process (5) が返されるプロセスタイプを持ちます。
専用アイコン からもワーカープロセスを識別することができます。
参照
ワーカーの使い方の詳細については、このブログ記事 を参照ください。
セマフォ
セマフォを使用すると、2つ以上のプロセスが同じリソース (ファイル、レコードなど) を同時に変更しないようにできます。セマフォを設定したプロセスのみが、それを解除できます。
シグナル もインタラクションの管理に使用できます。シグナルを使用すると、1つ以上のプロセスが特定のタスクの完了を待ってから実行を続行するようにできます。任意のプロセスがシグナルを待機したり、解放したりできます。
セマフォとは何か?
コンピュータープログラムにおいて、セマフォは、一度に1つのプロセスまたはユーザーのみが実行する必要のあるアクションを保護するために使用されるツールです。
4Dにおいてセマフォを使用する一般的なニーズは、プロセス間配列を変更することにあります。あるプロセスが配列の値を変更している場合、別のプロセスが同時に同じことをできてはなりません。開発者はセマフォを使用して、他のプロセスがすでに同じタスクを実行していない場合にのみ、プロセスが一連の処理を実行できることを示します。プロセスがセマフォに遭遇したとき、3つの可能性があります:
- ただちに通過する権利を得る
- 通過する権利を得るまで順番を待つ
- タスクの実行をあきらめて、そのまま進む。
したがって、セマフォはコードの一部を保護します。一度に1つのプロセスのみを通過させ、現在使用権を保持しているプロセスがセマフォを解放してその権利を手放すまでアクセスをブロックします。
セマフォを操作するためのコマンド
4Dでは、Semaphore コマンドを呼び出してセマフォを設定します。セマフォを解放するには、CLEAR SEMAPHORE コマンドを呼び出します。
Semaphore コマンドは、潜在的に2つのアクションを同時に実行するため、非常に特殊な動作をします:
- セマフォがすでに割り当てられている場合、関数は True を返します
- セマフォが割り当てられていない場合、関数はそれをプロセスに割り当て、同時に False を返します。
同じコマンドによっておこなわれるこの二重のアクションは、セマフォのテストとその割り当てのあいだに外部の操作が挿入されないことを保証します。
Test semaphore コマンドを使用すると、セマフォがすでに割り当てられているかどうかを知ることができます。このコマンドは主に、年次の決算処理などの長時間にわたる操作の一環として使用され、Test semaphore を使うことで、会計データの追加などの特定の操作へのアクセスを防ぐようにインターフェースを制御できます。
セマフォの使用方法
セマフォは、次の原則に従って使用する必要があります:
- セマフォは同じメソッド内で設定し、解放しなければなりません。
- セマフォによって保護されるコードの実行は、できる限り短くしなければなりません。
- セマフォの解放を待つために、コードは
Semaphoreコマンドの tickCount 引数によってタイミングを設定しなければなりません。
セマフォを使用する典型的なコードは次のとおりです:
While(Semaphore("MySemaphore";300))
IDLE
End while
// セマフォによって保護されるコードをここに置く
CLEAR SEMAPHORE("MySemaphore")
解放されないセマフォは、データベースの一部をブロックする可能性があります。セマフォの設定と解放を同じメソッド内でおこなうことは、このリスクを排除するのに役立ちます。
セマフォによって保護されるコードを最小限に抑えることで、アプリケーションの流動性が高まり、セマフォがボトルネックとして機能するのを防ぎます。
最後に、Semaphore コマンドのオプションの tickCount 引数を使用することは、セマフォの解放待ちを最適化するために不可欠です。この引数を使用すると、コマンドは次のように動作します:
- プロセスは、コードの実行が次の行に進むことなく、セマフォが利用可能になるまで、指定された tick 数 (この例では300) を最大として待機します。
- この制限の終了前にセマフォが解放された場合、それはただちにプロセスに割り当てられ (Semaphore は False を返します)、コードの実行が再開されます。
- この制限の終了前にセマフォが解放されない場合、コードの実行が再開されます。
このコマンドは、待ち行列を確立することでリクエストに優先順位を付けることもします。このようにして、セマフォを最初にリクエストしたプロセスが最初にそれを取得します。待機時間は、アプリケーションの仕様に応じて設定されることに注意してください。
ローカルセマフォまたはグローバルセマフォ
4Dには2種類のセマフォがあります: ローカルセマフォとグローバルセマフォです。
- ローカルセマフォは、同じワークステーション上のすべてのプロセスからアクセス可能で、そのワークステーション上でのみアクセスできます。ローカルセマフォは、セマフォの名前にドル記号 ($) を接頭辞として付けることで作成できます。ローカルセマフォは、同じワークステーション上で実行されるプロセス間の操作を監視するために使用します。たとえば、ローカルセマフォは、シングルユーザーデータベースまたはワークステーション上のすべてのプロセスによって共有されるプロセス間配列へのアクセスを監視するために使用できます。
- グローバルセマフォは、すべてのユーザーとそのすべてのプロセスからアクセス可能です。グローバルセマフォは、マルチユーザーデータベースのユーザー間の操作を監視するために使用します。
グローバルセマフォとローカルセマフォは、その論理においては同一です。違いはそのスコープにあります。
クライアント/サーバーにおいて、グローバルセマフォは、すべてのクライアントとサーバー上で実行されるすべてのプロセス間で共有されます。ローカルセマフォは、それが作成されたマシン上で実行されるプロセス間でのみ共有されます。
シングルユーザーの4Dアプリケーションでは、あなたが唯一のユーザーであるため、グローバルセマフォとローカルセマフォは同じスコープを持ちます。ただし、データベースが両方の構成で使用されている場合は、おこないたいことに応じてグローバルセマフォまたはローカルセマフォを使用するようにしてください。
注: インターフェースやプロセス間変数の配列など、アプリケーションのクライアントのローカルな側面を管理するためにセマフォが必要な場合は、ローカルセマフォの使用を推奨します。この場合にグローバルセマフォを使用すると、不要なネットワーク交換を引き起こすだけでなく、他のクライアントマシンに不必要に影響を与える可能性もあります。ローカルセマフォを使用すれば、これらの望ましくない副作用を回避できます。