並行パスカル
| 並行パスカル | |
|---|---|
| パラダイム | 命令型、構造化型、同時型 |
| 家族 | ヴィルト・ パスカル |
| デザイン: | ペル・ブリンチ・ハンセン |
| 初登場 | 1974年4月 |
| タイピングの規律 | 静的と動的、強力、安全 |
| プラットフォーム | 12月 PDP 11 |
| 影響を受けた | |
| ALGOL 60、Simula 67、Pascal | |
Concurrent Pascalは、 Per Brinch Hansenによって設計されたプログラミング言語で、共有メモリコンピュータ上のオペレーティングシステムやリアルタイムコンピューティング監視システムなどの並行コンピューティングプログラムを作成するために設計されました。[1]
Concurrent Pascalで書かれたオペレーティングシステム上で実行されるアプリケーションプログラム用の言語として、別の言語であるSequential Pascalが使用されています。どちらの言語もニクラウス・ヴィルトのPascalの拡張であり、共通のスレッドコードインタープリタを共有しています。[2]以下では、Concurrent PascalとヴィルトのPascalの違いについて説明します。
言語の説明
Pascalのいくつかの構成要素は、シンプルさとセキュリティのためにConcurrent Pascalから削除されました。[2]
- バリアントレコード
- Goto文とラベル
- パラメータとしての手順
- パック配列
- ポインタ型
- ファイルの種類と関連する標準入出力手順
これらの省略により、コンパイル時のチェックとスレッドコードインタープリタでの最小限の実行時チェックを組み合わせることで、プログラムが割り当てられた空間外をアドレス指定することによって自分自身や他のプログラムに損害を与えることができないことを保証できます。
Concurrent Pascal には、クラス、モニター、プロセスの各データ型が含まれます。これらの型のインスタンスは変数として宣言され、initステートメントで初期化されます。
クラスとモニターは似ています。どちらもプライベート変数とプロシージャをパブリックプロシージャ(プロシージャエントリと呼ばれる)にパッケージ化します。クラスインスタンスは1つのプロセスでのみ使用できますが、モニターインスタンスは複数のプロセスで共有できます。モニターは、Concurrent Pascalプログラムにおけるプロセス間通信の唯一のメカニズムを提供します。
特定のモニターインスタンス内では、一度に1つのプロセスしか実行できません。組み込みデータ型のキューは、操作およびとともにdelay、continueモニター内のスケジューリングに使用されます。キュー型の各変数は1つのプロセスを保持できます。モニター内で複数のプロセスを遅延させる場合は、通常は配列として構成される複数のキュー変数を用意する必要があります。単一のプロセスキュー変数を使用することで、モニターは中期的なスケジューリングを完全に制御できますが、適切なプロセスのブロックを解除するのはプログラマの責任です。
プロセスは、クラスやモニターと同様に、ローカル変数、プロシージャ、初期文を持ちますが、プロシージャのエントリは持ちません。初期文は通常、ローカルプロシージャ、クラスプロシージャ、モニタープロシージャを呼び出しながら、永久に実行されます。プロセスはモニタープロシージャを介して通信します。言語規則は、モニターに階層構造を課すことでデッドロックを防止します。しかし、モニターが遅延プロセスのブロック解除を誤って忘れてしまう(continueを呼び出さない)ことを防ぐことはできません。そのため、プログラミングエラーによってシステムが事実上ハングアップしてしまう可能性があります。
Concurrent Pascalプログラムにおけるプロセス、モニター、クラスの設定は通常、実行開始時に確立され、その後は変更されません。これらのコンポーネント間の通信パスはinit、ステートメントに渡される変数によって確立されます。クラスおよびモニターのインスタンス変数は、プロシージャのパラメータとして使用できないためです。
例
次の例は、単純なモニターの宣言と、通信する 2 つのプロセスによるそのモニターの使用を示しています。
「境界バッファモニター」と入力する バッファ = モニター var saved : 整数; 「保存された項目は整数です」 fullq, emptyq : キュー; 「2 つのプロセスでのみ使用されます」 full : ブール値; 「項目が保存されている場合は true:」 「アイテムをバッファに入れる」procedure entry put(item : Integer);始めるif full thendelay(fullq); "満杯の場合はブロック" saved := item; "アイテムを保存する" full := true; "満杯としてマークする" continue(emptyq) "消費者のブロックを解除する" 終わり; 「バッファからアイテムを取得します」procedure entry get(var item : Integer);始めるif not full thendelay(emptyq); "空の場合はブロック" item := saved; "アイテムを取得" full := false; "満杯でないとマーク" continue(fullq) "プロデューサーのブロックを解除" 終わり; 「モニターを初期化する」 始める 完全 := 偽 終わり; 「プロデューサーはバッファを使用する」 プロデューサー = プロセス(pass : バッファ);var item : Integer;始める cycle "ループを永久に実行する" "アイテムを生成する" pass.put(item) "アイテムをモニターに渡す" 終わり 終わり; 「消費者はバッファを使用する」 コンシューマー = プロセス(pass : バッファ);var item : Integer;始める サイクル pass.get(item); 「モニターからアイテムを取得する」 「アイテムを消費する」 終わり 終わり;「モニター、プロデューサー、コンシューマーのインスタンスを宣言する」「プロデューサーとコンシューマーにモニターへのアクセス権を与える」var pass : バッファ; prod : プロデューサー; 短所:消費者;始める init pass、 「モニターを初期化する」、 prod(pass)、 「プロデューサー プロセスを開始する」、 cons(pass) 、「コンシューマー プロセスを開始する」、 end。
参考文献
- ^ Brinch Hansen, Per (1975年6月). 「プログラミング言語 Concurrent Pascal」(PDF) . IEEE Transactions on Software Engineering (2): 199– 207. doi :10.1109/tse.1975.6312840.
- ^ ab Brinch Hansen, Per (1977). 『並行プログラムのアーキテクチャ』 Prentice Hall. ISBN 978-0-13-044628-2。