version 11 (Modified)
Semaphore (semaphore{; tickCount}) ブール
| 引数 | 型 | 説明 | |
| semaphore | 文字列 | テストと設定を行うセマフォ | |
| tickCount | 整数 | 最大待ち時間 | |
| 戻り値 | ブール | FALSE: セマフォの設定に成功した | |
| TRUE: 既にセマフォが存在する |
説明
セマフォは、ワークステーション (各ユーザのコンピュータ) 間、または同一ワークステーション上のプロセス間で共有されるフラグです。セマフォは、単に存在したり存在しなかったりするだけです。各ユーザが実行しているメソッドでセマフォの存在を調べることができます。セマフォを作成する、またはその存在の有無を調べることにより、ワークステーション間でのメソッドの通信が可能になります。
Semaphoreは、semaphoreが存在する場合にTRUEを返します。semaphoreが存在しない場合、Semaphoreはセマフォを作成し、FALSEを返します。同時に1人のユーザしかセマフォを作成することはできません。SemaphoreがFALSEを返すということは、セマフォが存在しなかったことを意味すると同時に、コマンド呼び出したプロセスに対して新たにセマフォ設定されたことを意味します。
Semaphoreは、セマフォが設定されていなければFALSEを返します。またコマンドを呼び出したプロセスが既にそのセマフォを設定している場合もFALSEを返します。semaphoreは先頭の$を含めて255文字以内に制限されています。これより長い文字列を指定すると、切り捨てられた文字列を使ってセマフォがテストされます。
オプションの引数tickCountは、semaphoreが既にセットされている時の待ち時間 (tick) を設定します。
この場合、関数はセマフォが解放されるか、またはTrueを返す前に待ち時間が終了まで待ちます。
4Dには2種類のセマフォ、ローカルセマフォとグローバルセマフォがあります。
・ローカルセマフォは、同じワークステーション上のすべてのプロセスからアクセスすることができます (同一ワークステーション上に限られます) 。ローカルセマフォは、セマフォ名の先頭にドル記号 ($) を付けて作成します。ローカルセマフォは、同一ワークステーション上で実行しているプロセス間で処理を監視する際に使用します。例えばローカルセマフォを使用して、シングルユーザデータベースやワークステーション上のすべてのプロセスで共用するインタープロセス配列へのアクセスを監視します。
・グローバルセマフォは、すべてのユーザとそのプロセスからアクセスすることができます。グローバルセマフォはマルチユーザデータベースのユーザ間で処理を監視するために用います。
グローバルセマフォとローカルセマフォは理論的には同じものです。違いはその有効範囲にあります。4D Serverでは、グローバルセマフォはすべてのクライアントで実行しているすべてのプロセス間で共用されます。ローカルセマフォは、それが作成されたクライアント上で実行しているプロセス間でのみ共用されます。スタンドアロンモードの4Dでは、ユーザは一人だけなため、グローバルセマフォもローカルセマフォもその有効範囲は同じです。ただし、シングルとマルチの両方の形でデータベースを使用する場合は、用途によってグローバルセマフォとローカルセマフォを使い分けてください。
セマフォはレコードのアクセスの保護目的には使用しません。これは4Dと4D Serverが自動的に行います。セマフォは、複数のユーザが同じ処理を同時に実行するのを防ぐために用います。
例題
1. 以下の例では、2人のユーザがProducts テーブルの価格を更新するのを防ぎます。以下のメソッドではセマフォを用いて、これを実現しています:
If (Semaphore("UpdatePrices")) ` セマフォの作成を試行
ALERT("Another user is already updating prices. Retry later.")
Else
DoUpdatePrices ` 料金の更新
CLEAR SEMAPHORE("UpdatePrices")) ` セマフォをクリア
End if
2. 以下の例はローカルセマフォを使用します。複数のプロセスを持つデータベースで、To Doリストを管理する必要があるとします。このリストはテーブルではなく、インタープロセス配列で管理します。セマフォを使って同時にアクセスされるのを防ぎます。このような場合に、To Doリストは自分だけのものなため、ローカルセマフォで十分です。
インタープロセス配列はOn Startup データベースメソッドで初期化します:
ARRAY TEXT(<>ToDoList;0) ` The To Do list is initially empty
To Doリストに項目を追加するメソッドを次に示します:
` ADD TO DO LIST project method
` ADD TO DO LIST ( Text )
` ADD TO DO LIST ( To do list item )
C_TEXT($1)
If(Not(Semaphore("$AccessToDoList";300)))
` Wait 5 seconds if the semaphore already exists
$vlElem:=Size of array(<>ToDoList)+1
INSERT IN ARAY(<>ToDoList;$vlElem)
<>ToDoList{$vlElem}:=$1
CLEAR SEMAPHORE("$AccessToDoList") ` Clear the semaphore
End if
どのプロセスからも上記メソッドを呼び出せます。
参照
CLEAR SEMAPHORE, Test semaphore.