結合パターン

結合パターン
パラダイム並行コンピューティング分散プログラミング
開発者インリアインリア
Webサイトインリア参加
主要な実装
Java、ポリフォニック C #、統合並列 C結合ライブラリBoost を結合します。
影響を受けた
微積分に参加する

ジョインパターンは、メッセージパッシングを用いて並行並列分散型のコンピュータプログラムを記述する方法を提供します。スレッドやロックの使用と比較して、これは通信構造モデルを用いて並行環境の複雑さを抽象化し、スケーラビリティを実現する高水準のプログラミングモデルです。これは、チャネルグループからアトミックに消費されるメッセージ間の コード実行に重点を置いています。

このテンプレートは結合計算に基づいており、パターンマッチングを使用します。具体的には、同時呼び出しとメッセージパターンをマッチングすることで、複数の関数やチャネルの結合定義を可能にします。これは、これらのエンティティがより容易かつ柔軟に通信し、マルチスレッドプログラミングパラダイムを処理できるようにするため、並行性パターンの一種です。

説明

結合パターン(またはのコード)は、同期とマッチングを備えたスーパーパイプラインのようなものです。実際、この概念は、異なるメッセージキューから利用可能な一連のメッセージを一致させて結合し、それらをすべて1つのハンドラーで同時に処理することで要約されます。[ 1 ]これはwhen、最初の通信を指定するキーワード、and他のチャネルを結合/ペアリングするキーワード、そしてdo収集された異なるメッセージを使用していくつかのタスクを実行するキーワードで表すことができます。構築された結合パターンは通常、次の形式になります。

j.When(a1).And(a2). ... .And(an).Do(d) 

の引数a1When(a1)は、同期チャネル、非同期チャネル、または非同期チャネルの配列です。以降の引数ai( )は非同期チャネルでなければなりません。[ 2 ]And(ai)i > 1

より正確には、メッセージがリンクされたパターンのチェーンと一致すると、そのハンドラが実行されます(非同期コンテキストの場合は新しいスレッドで実行されます)。それ以外の場合は、パターンの1つが有効になるまでメッセージはキューに入れられます。複数のパターンが一致する場合は、指定されていないパターンが選択されます。[ 3 ]

イベントハンドラは複数の代替イベントのうちの1つを、そのイベントの他のすべてのハンドラと組み合わせて一度に処理しますが、結合パターンはチャネルの結合を待機し、他の有効なパターンと実行を競合します。[ 4 ]

このフロー図は、異なるチャネルとの一般的な一致によって結合パターンが実行され (コードを待機)、リソースが同期される (解放またはロック) 方法を示しています。

Joinパターンは、送信と受信という2つの異なる操作をサポートするπ計算チャネルxの集合によって定義されます。これを実装するには、2つのJoin計算名が必要です。送信(メッセージ)用のチャネル名xと、値(リクエスト)の受信用の関数名xです。Join定義の意味は、への呼び出しがチャネルに送信された値を返すことです。関数が同時に実行されるたびに、戻り処理がトリガーされ、他のJoinと同期されます。[ 5 ]x()x<>

J ::= //結合パターン| x < y > //メッセージ送信パターン| x ( y ) //関数呼び出しパターン| J | JBIS //同期

クライアントの視点から見ると、チャネルは同じ名前とシグネチャを持つメソッドを宣言しているだけです。クライアントは、チャネルをメソッドとして呼び出すことで、メッセージを投稿したり、リクエストを発行したりします。継続メソッドは、継続のWhen節に続く各チャネルにリクエストまたはメッセージが1つでも到着するまで待機する必要があります。継続が実行される場合、各チャネル呼び出しの引数はキューから取り出され(つまり消費され)、継続のパラメータに(アトミックに)転送されます。[ 6 ]

Joinパターンのクラス図

ほとんどの場合、パフォーマンス上の理由から、同期呼び出しの順序は保証されません。さらに、試合中にキュー内のメッセージが介入中のスレッドによって奪われる可能性があり、実際には、起動されたスレッドが再び待機しなければならない場合もあります。[ 7 ]

歴史

π計算 – 1992

π計算はプロセス計算のファミリーに属し、チャネル名をチャネル自体に沿って通信することで並行計算の特性を記述および分析するための数学的形式を可能にし、このようにして計算中にネットワーク構成が変化する可能性がある並行計算を記述することができます。

Join-Calculus – 1993

ジョインパターンは、分散環境での効率的な実装のために設計された非同期プロセス代数である、FournetとGonthierの基礎的なジョイン計算で初めて登場しました。[ 8 ]ジョイン計算は、完全なπ計算と同等の表現力を持つプロセス計算です。分散プログラミング言語の設計のための正式な基盤を提供するために開発されたため、ランデブー通信など、他のプロセス計算に見られる通信構造を意図的に避けています。

分散結合計算 – 1996

Join計算は名前渡し計算であると同時に、並行・分散プログラミングのコア言語でもある。[ 9 ]そのため、分散プログラミングを備えたJoin計算に基づく分散Join計算[ 10 ]が1996年に作成された。この研究では、エージェントがプログラムであるだけでなく、通信機能を備えた実行中のプロセスのコアイメージであるモバイルエージェントを使用する。

JoCaml、Funnel、Join Java – 2000

JoCaml [ 11 ] [ 12 ]とFunnel [ 13 ] [ 14 ]は、宣言的な結合パターンをサポートする関数型言語です。これらは、関数型の設定においてプロセス計算を直接実装するためのアイデアを提示しています。

Javaの別の拡張(非ジェネリック)であるJoinJavaは、von ItzsteinとKearneyによって独立して提案されました。[ 15 ]

ポリフォニックC# – 2002

Cardelli、Benton、Fournetは、C#の結合パターンのオブジェクト指向バージョンであるPolyphonic C#を提案した。[ 16 ]

Cω – 2003

Cωは結合計算をオブジェクト指向環境に適応させたものである。[ 17 ]このポリフォニックC#の変種は、2004年にCω(別名Comega)の一般公開リリースに含まれていた。

Scala 参加 – 2007

Scala Joinsは、ScalaのJoin-Patternを拡張可能なパターンマッチングのコンテキストで使用し、既存のアクターベースの並行性フレームワークに結合を統合するためのライブラリです。[ 18 ]

ジェラン – 2009

Erlangは、並行性、リアルタイム性、分散性をネイティブにサポートする言語です。プロセス間の並行性は複雑であったため、このプロジェクトではJoin計算に基づいた新しい言語、JErlangJはJoinの略)を開発しました。

古典的なプログラミング文献における結合パターン

「結合パターンは、アクターやアクティブオブジェクトのような関連する並行性のイディオムを簡単にエンコードするために使用できます。」[ 19 ]

Microsoft.Research.Joinsを使用しますクラスSymmetricBarrier { public readonly Synchronous.Channel Arrive ;public SymmetricBarrier ( int n ) { // j を作成し、チャネルを初期化する (省略) JoinPattern pat = j . When ( Arrive ); for ( int i = 1 ; i < n ; i ++ ) { pat = pat . And ( Arrive ); } pat . Do (() => { }); } }
Microsoft.Research.Joinsを使用しますJoin j = Join.Create ( ) ;同期.Channel [ ] hungry ;非同期.Channel [ ] chopstick ; j.Init ( out hungry , n ) ; j.Init ( out chopstick , n ) ;for ( int i = 0 ; i < n ; i ++ ) {非同期チャネルleft = chopstick [ i ];非同期チャネルright = chopstick [( i + 1 ) % n ]; j . When ( hungry [ i ] ). And ( left ). And ( right ). Do (() => { eat (); left (); right (); // 箸を交換する}); }
Microsoft.Research.Joinsを使用しますクラスLock { public readonly Synchronous.Channel Acquire ; public readonly Asynchronous.Channel Release ;public Lock () { // j を作成し、チャネルを初期化する (省略) j . When ( Acquire ). And ( Release ). Do (() => { }); Release (); // 最初は解放されている} }
Microsoft.Research.Joinsを使用しますクラスBuffer < T > { public readonly Asynchronous.Channel < T > Put ; public readonly Synchronous < T > .Channel Get ;public Buffer () { Join j = Join.Create ( ); // Join オブジェクトを割り当てますj.Init ( out Put ) ; //チャネルをバインドしますj.Init ( out Get ) ; j.When ( Get ) .And ( Put ) .Do // chord ( t = > { return t ; } ) ; } }
Microsoft.Research.Joinsを使用しますクラスReaderWriterLock { private readonly Asynchronous.Channel idle ; private readonly Asynchronous.Channel <int> shared ; public readonly Synchronous.Channel AcqR AcqW RelR RelW ;public ReaderWriterLock () { // j を作成し、チャネルを初期化します (省略) j . When ( AcqR ). And ( idle ). Do (() => shared ( 1 )); j . When ( AcqR ). And ( shared ). Do ( n => shared ( n + 1 )); j . When ( RelR ). And ( shared ). Do ( n => { if ( n == 1 ) { idle (); } else { shared ( n - 1 ); } }); j . When ( AcqW ). And ( idle ). Do (() => { }); j . When ( RelW ). Do (() => idle ()); idle (); // 最初は解放} }
Microsoft.Research.Joinsを使用しますクラスSemaphore { public readonly Synchronous.Channel Acquire ; public readonly Asynchronous.Channel Release ;public Semaphore ( int n ) { // j を作成し、チャネルを初期化します (省略) j . When ( Acquire ). And ( Release ). Do (() => { }); while ( n > 0 ) { Release (); // 最初は n が解放されています-- n ; } } }

基本的な機能と概念

  • Join 計算 : Join パターンが最初に現れたのは、このプロセス計算です。
  • メッセージ パッシング : Join パターンは、並列処理のためにメッセージ パッシング システムと連携して機能します。
  • チャネル :チャネルは、同時実行中のスレッド間で同期を取り、メッセージを渡すために使用されます。一般的に、チャネルは複数の結合パターンに関与する可能性があり、各パターンはチャネルが呼び出されたときに実行される異なる継続を定義します。[ 6 ]
  • 同期 :joinパターンは、結果を返す同期チャネルを使用できます。同期パターンの継続は、同期送信者のスレッド内で実行されます。[ 6 ]
  • 非同期 :結果を返さずに引数を受け取る非同期チャネルを使用することもできます。非同期パターンの継続は、新たに生成されたスレッドで実行されます。結合パターンは、その継続がサブルーチンであり、When節に非同期チャネルのみを列挙している場合、完全に非同期にすることができます。[ 6 ]
  • 同期と非同期を組み合わせる:同期バッファと非同期バッファの宣言を統合すると、2つの通信タイプのコンシューマをサポートするモジュールが生成されます。[ 6 ]
  • スケジューラ : 結合パターン間のスケジューリングがあります(例:ラウンドロビンスケジューラ、ファーストマッチスケジューラ)。[ 6 ]
  • デザイン パターン : 結合パターンは、まず第一に動作と同時実行のパターンです。
  • 並行プログラミング : 並行して実行します。
  • パターン マッチング : 結合パターンは、一致するタスクで機能します。
  • 並列プログラミング : タスクを並列に実行します。
  • 分散プログラミング : このパターンを使用すると、ジョブをさまざまなエージェントや環境に分散させることができます。
  • ソフトウェア トランザクション メモリ : ソフトウェア トランザクション メモリ (STM) は、ジョイント間の通信の可能な実装の 1 つです。
  • 重複 : パターンでは、重複するチャネル セットで宣言されたパターンが許可されます。

アプリケーションドメイン

モバイルエージェント

モバイルエージェントは、一定の社会的能力と、最も重要な機動性を備えた自律型ソフトウェアエージェントです。モバイルエージェントは、複数のコンピュータ間で自動的に移動しながら実行を継続できるコンピュータソフトウェアとデータで構成されています。

モバイルエージェントは、Join計算を用いることで、並行性と分散性を両立させることができます。そのため、「分散Join計算」という新しい概念が生まれました。これは、Join計算を拡張し、位置とプリミティブを用いて移動性を記述するものです。この革新は、エージェントを通信機能を持つ実行プロセスとして用いることで、エージェントの実際の位置を表す物理的な場所、つまり位置の概念を実現します。Join計算のおかげで、ある場所を別の場所にアトミックに移動させることができます。[ 24 ]

エージェントのプロセスは、非同期メッセージの送信や他のロケーションへの移動といった機能を定義する集合として定義されます。その結果、ロケーションはツリー構造に整理され、エージェントの移動をより容易に表現できます。この表現により、このソリューションの利点は、シンプルな障害モデルを作成できることです。通常、物理サイトのクラッシュは、そのすべてのロケーションで永続的な障害を引き起こします。しかし、結合計算を用いることで、あるロケーションで発生した問題を他の実行中のロケーションで検出し、エラー回復が可能になります。[ 24 ]

したがって、Join計算は分散プログラミング言語の中核を成す。特に、操作的意味論は、障害発生時の分散環境においても容易に実装可能である。そのため、分散Join計算は、チャネル名とロケーション名を語彙スコープを持つ第一級の値として扱う。ロケーションは自身の移動を制御し、受信した名前を持つロケーションに向かってのみ移動することができる。これは、静的解析と安全な移動のための堅実な基盤を提供する。これは分散構成を表現する上で完全なものである。しかし、障害が発生しない場合、プロセスの実行は分散とは独立している。このロケーションの透明性は、モバイルエージェントの設計に不可欠であり、その特性を確認する上で非常に役立つ。[ 24 ]

2007年には、エージェントを能動的にするための手法を含む基本的な結合計算の拡張が発表されました。エージェントは、エージェント間で共有される環境を観察できます。この環境を用いることで、すべてのエージェント間で共有される変数(例えば、エージェント同士でエージェントを発見するための命名サービス)を定義することが可能になります。[ 25 ]

コンピレーション

結合言語は、結合計算をコア言語としてその上に構築されます。そのため、すべての計算は非同期プロセスで分析され、結合パターンは結果を同期するためのモデルを提供します。[ 9 ] これを実現するために、2つのコンパイラが存在します。

この 2 つのコンパイラは同じシステム、つまりオートマトンで動作します。

A(n) | B() = P(n) とします。 そしてA(n) | C() = Q(n) ;; 

これは、完了した結合モデルに到着したメッセージの消費を表します。各状態はコード実行の可能なステップであり、各遷移は2つのステップ間の切り替えのためのメッセージの受信です。したがって、すべてのメッセージが取得されると、コンパイラは完了したモデル結合に対応する本体結合コードを実行します。

結合計算では、基本的な値は例のA、B、Cのような名前です。そのため、2つのコンパイラはそれぞれ2つの方法でこの値を表します。 結合コンパイラは2つのスロットを持つベクトルを使用します。1つ目は名前自体、2つ目は保留中のメッセージのキューです。Jocaml は名前を定義のポインタのように使用します。この定義は、ステータスフィールドとメッセージごとの一致する日付構造を持つ、他の名前へのポインタを格納します。 基本的な違いは、ガードプロセスが実行されるとき、最初の場合はすべての名前が保留中のメッセージの準備ができているかどうかを確認するのに対し、2番目の場合は1つの変数のみを使用し、他の変数にアクセスしてモデルが完了したかどうかを確認します。[ 9 ]

最近の研究では、コンパイル方式はディスパッチと転送という2つの基本ステップの組み合わせであると説明されている。ディスパッチャの設計と正確性は本質的にパターンマッチング理論に由来するが、通信に内部転送ステップを挿入することは自然なアイデアであり、直感的にはプロセスの動作を変更しない。彼らは、拡張された結合パターンマッチングをランタイムレベルで直接実装すると、メッセージキューの管理が著しく複雑になり、メッセージを消費する前に一致するメッセージを探すためにキューをスキャンする必要があるという点に注目に値すると指摘した。[ 26 ]

実装とライブラリ

Joinパターンは様々な言語で多様に利用されています。Polyphonic C#MC#のように、Joinパターンを実装のベースとして用いる言語もありますが(Wayback Machineに2011年9月10日アーカイブ) 、Scala Joins [ 27 ]やVB Joinsライブラリ[ 28 ]といったライブラリによってJoinパターンが統合されている言語もあります。さらに、 Schemeなどの言語ではJoinパターンをアップグレードするためにJoinパターンが用いられています。 [ 29 ]

ジェランCBライブラリに参加ポリフォニック C#並列C#Scalaの結合F#スキームJavaに参加ヒュームジョカムル
パターンマッチングはいはいはいはいはいはいはいはいはいはいはいはい
結合パターン間のスケジューラはい:最初の一致はい:第1ラウンド/ラウンドロビンはいはいはいはいはいはいいいえはい:ランダムはい:第1ラウンド/ラウンドロビンはい:ランダム
ジェネリック医薬品はい該当なしはいいいえ該当なしいいえはいはいいいえいいえいいえいいえ
オーバーライドいいえはい該当なし該当なし該当なしはいはいはいいいえはいいいえいいえ

Javaに参加

Join Java [ 30 ]は、 Javaプログラミング言語をベースにした言語で、結合計算を使用することができます。3つの新しい言語構成要素を導入しています。

  • Joinメソッドは、2つ以上のJoinフラグメントによって定義されます。Joinパターンのすべてのフラグメントが呼び出されると、Joinメソッドが実行されます。戻り値の型が標準Java型の場合、先頭のフラグメントは、Joinパターンが完了してメソッドが実行されるまで呼び出し元をブロックします。戻り値の型がsignal型の場合、先頭のフラグメントは直ちに戻ります。末尾のフラグメントはすべて非同期であるため、呼び出し元をブロックしません。

例:

class JoinExample { int fragment1 () & fragment2 ( int x ) { // fragment1 の呼び出し元に x の値を返しますreturn x ; } }
  • 非同期メソッドは、signal 戻り値型を使用して定義されます。これは、メソッドが即座に返される点を除けば、void 型と同じ特性を持ちます。非同期メソッドが呼び出されると、メソッド本体を実行するために新しいスレッドが作成されます。

例:

class ThreadExample { signal thread ( SomeObject x ) { // このコードは新しいスレッドで実行されます} }
  • 順序修飾子

Joinフラグメントは複数のJoinパターンで繰り返すことができるため、フラグメントが呼び出される際に複数のJoinパターンが完了する場合があります。例えば、以下の例では、B()、C()、D()、A()が呼び出された場合にこのようなケースが発生する可能性があります。最後のA()フラグメントで3つのパターンが完了するため、呼び出される可能性のあるメソッドは3つあります。ここでは、どのJoinメソッドが呼び出されるかを決定するために、orderedクラス修飾子が使用されます。デフォルトでは、unorderedクラス修飾子を使用する場合、メソッドはランダムに1つ選択されます。ordered修飾子を使用すると、メソッドは宣言された順序に従って優先順位が付けられます。

例:

クラスはSimpleJoinPatternを順序付けしました{ void A () & B () { } void A () & C () { } void A () & D () { } signal D () & E () { } }

最も近い関連言語はポリフォニック C#です。

ジェラン

Erlangでは、複数のプロセス間の同期は容易ではありません。そのため、Erlangの拡張であるJErlang [ 31 ]が作成されました。JはJoin(結合)の略です。この制限を克服するために、Join計算に着想を得たErlangの拡張であるJErlangが実装されました。この言語の特徴は以下のとおりです。

  • 結合により、最初の一致セマンティクスが可能になり、メッセージの順序を維持しながら複数のパターンを持つ可能性が生まれます。
演算() ->受信{ ok , sum }{ val , X }{ val , Y } -> { sum , X + Y }; { ok , mult }{ val , X }{ val , Y } -> { mult , X * Y }; { ok , sub }{ val , X }{ val , Y } -> { sub , X - Y };終了終了
  • ガードはパターン表現ではない追加のフィルタリングを提供します。副作用のない表現の数は制限されています。
( Lower <= MかつM <= Upper )の場合、{ Transaction , M }および{ limit , Lower , Upper }を受け取ります-> commit_transaction ( M , Transaction )終了
  • 非線形パターンでは、メッセージは複数の結合に一致する可能性がある
{ get , X }{ set , X } -> { found , 2 , X }を受け取ります... { Pin , id }{ auth , Pin }{ commit , Id }受け取ります-> perform_transaction ( Pin , Id )を受け取ります
  • 伝播により、正しいメッセージを削除するのではなくコピーできるようになります。
prop ({ session , Id }){ act , Action , Id }を受け取ります-> perform_action ( Action , Id ) ; { session , Id }{ logout , Id } -> logout_user ( Id )を受け取ります... { Pin , id }{ auth , Pin }{ commit , Id }を受け取ります-> perform_transaction ( Pin , Id )を受け取ります
  • 同期呼び出し
受信{ accept , Pid1 }{ asynchronous , Value }{ accept , Pid2 } -> Pid1 ! { ok , Value }, Pid2 ! { ok , Value }終了

C++

Yigong Liu は、非同期および同期チャネル、コードなどのすべての便利なツールを含む結合パターン用のクラスをいくつか作成しました。これはBoostに統合されたようですが、2025 年時点では存在していないようです。

stdをインポートしますテンプレート< typename V >クラスBuffer : public Joint { public : Async < V > put ; Synchronous < V , void > get ;バッファ(){ chord get put Buffer :: chordBody ); }V chordBody ( void_t g , V p ) { return p ; } };

この例では、スレッドセーフなバッファとメッセージキューを、基本的な操作であるputとgetを使って示しています。[ 32 ]

C#

ポリフォニック C#

Polyphonic C#はC#プログラミング言語の拡張です。同期メソッドと非同期メソッド(呼び出し元に制御を返す)に加え、コード(「同期パターン」または「結合パターン」とも呼ばれます)を備えた新しい並行処理モデルを導入しています。

パブリッククラスBuffer { public String get () & public async put ( String s ) { return s ; } }

これは単純なバッファの例です。[ 33 ]

MC#

MC# 言語は、同時分散計算の場合に Polyphonic C# 言語を適応させたものです。

パブリックハンドラーGet2 long () &チャネルc1 ( long x ) &チャネルc2 ( long y ) { return ( x + y ); }

この例では、コードを同期ツールとして使用する方法を示します。

並列C#

Parallel C#は Polyphonic C# をベースとしており、可動メソッドや高階関数などの新しい概念がいくつか追加されています。

システムを使用しますクラスTest13 { int Receive () & async Send ( int x ) { return x * x ; }パブリック静的void Main ( string [ ] args ) { Test13t = new Test13 ( ) ; t.Send ( 2 ) ; Console.WriteLine ( t.Receive ( ) ) ; } }

この例では結合の使い方を示しています。[ 34 ]

Cωは、並行プログラミングをサポートする新しい言語機能を追加します(以前のPolyphonic C#に基づいています)。C#およびその他の.NET言語用のJoins並行性ライブラリはこのプロジェクトから派生しています。[ 35 ] [ 36 ]

スケーラブルな結合パターン

これは、宣言型でスケーラブルな、使いやすい結合パターンライブラリです。Russoライブラリ[ 28 ]とは対照的に、グローバルロックは備えていません。実際には、比較交換型CASとアトミックメッセージシステムを採用しています。このライブラリ[ 37 ]は、結合パターンに3つの改良を加えています。

  • 未使用のリソースに対するメッセージの盗難(割り込みを許可する)
  • 遅延キューは、楽観的な高速パスによる割り当てやエンキューを回避することで、割り当てとプロセッサ間通信の両方を節約します。
  • ステータス「WOKEN」: ブロックされた同期呼び出し元が 1 回だけ起動されることを保証します。

ジョカムル

JoCamlは、joinパターンが実装された最初の言語です。実際、当初は様々な実装がJoCamlコンパイラでコンパイルされていました。JoCaml 言語はOCaml言語の拡張であり、並行性と同期性、プログラムの分散実行、実行中のアクティブなプログラムフラグメントの動的な再配置などをサポートすることでOCamlを拡張しています。[ 38 ]

タイプコイン= Nickel | Dime ドリンク= Coffee | Tea ボタン= BCoffee | BTea | BCancel ;;(* def は Join パターンの set 句を定義します* = の左側の "&" は join (チャネル同期) を意味します* 右側の "&" は並列プロセスを意味します* synchronized_reply :== "reply" [x] "to" channel_name * 同期チャネルは関数のような型を持ちます (`a -> `b) * 非同期チャネルは型を持ちます (`a Join.chan) * パターンの rhs 式の最後のステートメントのみが非同期メッセージになることができます* 非同期メッセージの位置にある 0 は STOP (CSP 用語では "送信メッセージなし") を意味します。 *)def put ( s ) = print_endline s ; 0 (* STOP *) ;; (* put: string Join.chan *)def serve ( drink ) = drink をCoffee一致させる-> put ( "Cofee" ) | Tea -> put ( "Tea" ) ;; (* serve: drinks Join.chan *)def refund ( v ) = let s = Printf . sprintf "Refund %d" v in put ( s ) ;; (* refund: int Join.chan *)let new_vending serve refund = let vend ( cost : int ) ( credit : int ) = if credit >= cost then ( true , credit - cost ) else ( false , credit ) in def coin ( Nickel ) & value ( v ) = value ( v + 5 ) & reply () to coinまたはcoin ( Dime ) & value ( v ) = value ( v + 10 ) & reply () to coinまたはbutton ( BCoffee ) & value ( v ) = let should_serve , remainder = vend 10 v in ( if should_serve then serve ( Coffee ) else 0 (* STOP *) ) & value ( replain ) & reply ( ) to buttonまたはbutton ( BTea ) & value ( v ) = let should_serve , remainder = vend 5 v in ( if should_serve then serve ( Tea ) else 0 (* STOP *) ) & value ( remainder ) & reply () to buttonまたはbutton ( BCancel ) & value ( v ) = refund ( v ) & value ( 0 ) & reply ()buttonspawn value ( 0 ) ; coin , button (* coin, button: int -> unit *) ;; (* new_vending: drink Join.chan -> int Join.chan -> (int->unit)*(int->unit) *)let ccoin , cbutton = new_vending serve refund in ccoin ( Nickel ); ccoin ( Nickel ); ccoin ( Dime ); Unix.sleep ( 1 ) ; cbutton ( BCoffee ); Unix.sleep ( 1 ) ; cbutton ( BTea ) ; Unix.sleep ( 1 ); cbutton ( BCancel ); Unix.sleep ( 1 ) ( * 最後のメッセージが表示されるようする* ) ;;

与える

コーヒー お茶 払い戻し5 

ヒューム

Hume [ 39 ]は、非同期メッセージの受け渡し、データフロープログラミングHaskellのような構文に基づいた並行性を備えた、リソースが限られたプラットフォーム向けの厳密強く型付けされた関数型言語です。

Hume は同期メッセージングを提供しません。

共通のチャネルを持つ結合パターン セットをボックスとしてラップし、すべてのチャネルをinタプルにリストし、すべての可能な出力をoutタプルに指定します。

セット内のすべての結合パターンは、必須でないチャネルに '*' を指定するボックス入力タプル タイプに準拠し、出力タプルに準拠するタイプの式を指定して、入力されない出力に '*' をマークする必要があります。

ワイヤー条項は以下を指定し ます

  1. 対応する入力元またはソースとオプションの開始値のタプル
  2. 出力先のタプル。チャネルまたはシンク (stdout、..) です。

ボックスでは、出力タプルに準拠した式を使用して例外ハンドラーを指定できます。

データコイン= 50 セント| 10 セント;データドリンク=コーヒー|紅茶;データボタン= BCoffee | BTea | BCancel ;type Int = int 32 ; type String = string ; show u = u as string ;box coffee in ( coin :: Coins , button :: Buttons , value :: Int ) -- 入力チャネルout ( drink_outp :: String , value ' :: Int , refund_outp :: String ) -- 名前付き出力match -- * 未入力の出力および未消費の入力に対するワイルドカード( Nickel * v ) -> ( * v + 5 * ) | ( Dime * v ) -> ( * v + 10 * ) | ( * BCoffee v ) -> vend Coffee 10 v | ( * BTea v ) -> vend Tea 5 v | ( * BCancel v ) -> let refund u = "Refund " ++ show u ++ " \n " in ( * 0 refund v ) ;ドリンクを販売します。コストはクレジットです。クレジット>=コスト場合、 (ドリンクを提供クレジット-コスト* ) 、そうでない場合は( * クレジット* )。serve drink = case drink of Coffee -> "Cofee \n " Tea -> "Tea \n " ;ボックスコントロールin ( c :: char ) out ( coin :: Coins button :: Buttons )一致'n' -> ( Nickel * ) | 'd' -> ( Dime * ) | 'c' -> ( * BCoffee ) | 't' -> ( * BTea ) | 'x' -> ( * BCancel ) | _ -> ( * * ) ;console_outp を"std_out"ストリームします。console_inp"std_in"からストリームします-- データフロー配線wire cofee -- 入力(チャンネルの起点)control . coin control . button coffee . value '初期値は0 -- 出力先console_outp coffee . value console_outp ;ワイヤーコントロール( console_inp ) (コーヒー.コイン,コーヒー.ボタン) ;

ビジュアルベーシック

同時ベーシック – CB

Visual Basic 9.0の非同期並行性構造の拡張機能であるConcurrent Basic(略してCB)は、結合パターンを提供します。CB(ポリフォニックC#、Cω、および結合ライブラリの以前の成果に基づいて構築)は、VBプログラマに馴染みのある単純なイベントのような構文を採用し、汎用的な並行性の抽象化を宣言できるようにし、継承をより自然にサポートすることで、サブクラスでパターンセットを拡張できるようにします。CBクラスは、特定のローカルチャネルセットで非同期および同期の通信が発生したときに実行するメソッドを宣言し、結合パターンを形成できます。[ 28 ]

モジュールバッファパブリック非同期Put ( ByVal s As String )パブリック同期Take () As Stringプライベート関数CaseTakeAndPut ( ByVal s As String ) As String _ Takeの場合Put返すEnd Functionエンドモジュール

この例では、Concurrent Basicで使用されるすべての新しいキーワード、Asynchronous、Synchronous、Whenを示しています。[ 40 ]

結合ライブラリ (C# および VB)

このライブラリは、オブジェクトとジェネリックを用いてJoinパターンを高レベルで抽象化したものです。チャネルは、いくつかの共通Joinオブジェクト(メソッドではなく)からの特別なデリゲート値です。[ 41 ]

Microsoft.Research.Joinsを使用しますクラスBuffer { public readonly Asynchronous.Channel <文字> Put ; public readonly Synchronous <文字> .Channel Get ;public Buffer ( ) { Join join = Join.Create ( ) ; join.Initialize ( out Put ) ; join.Initialize ( out Get ) ; join.When ( Get ) .And ( Put ) .Do ( delegate ( string s ) { return s ; } ) ; } }

この例では、Joinオブジェクトのメソッドの使用方法を示しています。[ 42 ]

スカラ

Scala JoinsライブラリはJoinパターンを使用します。この言語のパターンマッチング機能は、パターンマッチングで使用されるオブジェクトの表現独立性を可能にするように一般化されています。これにより、ライブラリで新しいタイプの抽象化を使用できるようになりました。Joinパターンの利点は、異なるスレッド間の同期を宣言的に指定できることです。多くの場合、Joinパターンはオブジェクトの有効な状態を指定する有限状態機械と密接に対応しています。

Scalaでは、パターンマッチングとScala Joinsを使って、Reader-Writerなどの多くの問題を解決することができます。[ 27 ]

クラスReaderWriterLock はJoinsを拡張します{private val Sharing = new AsyncEvent [ Int ] val Exclusive , ReleaseExclusive = new NullarySyncEvent val Shared , ReleaseShared = new NullarySyncEvent join { case Exclusive () & Sharing ( 0 ) => Exclusive reply case ReleaseExclusive () => { Sharing ( 0 ); ReleaseExclusive reply } case Shared () & Sharing ( n ) => { Sharing ( n + 1 ); Shared reply } case ReleaseShared () & Sharing ( 1 ) => { Sharing ( 0 ); ReleaseShared reply } case ReleaseShared () & Sharing ( n ) => { Sharing ( n - 1 ); ReleaseShared reply } } Sharing ( 0 ) }

クラスでは、通常のフィールドでイベントを宣言します。そのため、Join構造を使用して、case宣言のリストによるパターンマッチングが可能になります。このリストは => で表され、それぞれの側に宣言の一部が記述されています。左側は、非同期イベントと同期イベントの組み合わせを示すjoinパターンのモデルであり、右側はjoinモデルが完了した時点で実行されるjoinの本体です。

Scalaでは、Scalaのアクターライブラリ[ 43 ]を結合パターンと共に使用することも可能です。例えば、無制限のバッファは次のようになります: [ 27 ]

val Put = new Join1 [ Int ] val Get = new JoinクラスBuffer はJoinActor を拡張します{ def act () { receive { case Get () & Put ( x ) => Get reply x } } }

Scala JoinChymyst はJoin パターンの新しい実装であり、Philipp Haller 博士のScala Joins を改良したものです。

ハスケル

Join Language は、Haskell の Join パターンの実装です。

スキーム

Joinパターンは、特にマルチコアアーキテクチャにおいて、高度な抽象化を伴う新しいプログラミングタイプを可能にします。これはガードとプロパゲーションに基づいています。この革新の一例はSchemeに実装されています。[ 29 ]

ガードは、一致するキーを持つデータのみが更新/取得されることを保証するために不可欠です。プロパゲーションはアイテムをキャンセルし、その内容を読み取り、アイテムをストアに戻します。もちろん、読み取り中もアイテムはストア内に存在します。ガードは共有変数で表現されます。そして、結合パターンに伝播された部分と簡略化された部分を含めることができるという点が新しい点です。Schemeでは、/ の前の部分が伝播され、/ の後の部分が削除されます。ゴールベースドの使用は、作業を複数のタスクに分割し、最後にすべての結果を結合パターンで結合することです。「MiniJoin」と呼ばれるシステムが実装されており、可能な場合は中間結果を使用して他のタスクを解決します。中間結果が使用できない場合は、他のタスクの解決を待機します。 そのため、マルチコアアーキテクチャ上で並列実行される同時結合パターンアプリケーションでは、並列実行によって競合が発生することを保証するものではありません。これと高度な並列性を保証するために、アトミックな比較・スワップ(CAS)に基づく高度に調整された並行データ構造内のソフトウェア・トランザクショナル・メモリ(STM)が使用されています。これにより、マルチコア・アーキテクチャ上で多数の同時操作を並列に実行できます。さらに、CASとSTM間の「誤った競合」を防ぐために、アトミック実行が採用されています。[ 29 ]

その他の類似したデザインパターン

結合パターンは、マルチタスクを実行する唯一のパターンではありませんが、リソース間の通信、同期、および異なるプロセスの結合を可能にする唯一のパターンです。

  • シーケンスパターン:タスクが完了するまで待ってから別のタスクに切り替える(古典的な実装)。[ 44 ]
  • 分割パターン(並列分割):複数のタスクを同時に並列に実行する(例:Map reduce)。[ 45 ]

参照

  • Joins (同時実行ライブラリ) – Joins は、.NET Framework 用の Microsoft Research の非同期同時実行コンピューティング API です。
  • 結合計算– 結合計算は、分散プログラミング言語の設計に正式な基盤を提供するために開発されました。
  • アクターモデル- メッセージパッシングを使用するスレッドの別の代替手段

参考文献

注記

  1. ^ Taral Dragon (2009年10月25日). 「Join Calculus」 .
  2. ^ Russo, Claudio V. (2008年10月23日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 10. doi : 10.1145/1449955.1449770 .
  3. ^ 「並列C#」
  4. ^ Russo, Claudio V. (2008年10月27日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 2. doi : 10.1145/1449955.1449770 .
  5. ^ Fournet, Cédric; Gonthier, Georges (2002). 「Join Calculus: 分散モバイルプログラミング言語」.応用意味論. コンピュータサイエンス講義ノート. 第2395巻. Springer. pp.  268– 332. CiteSeerX 10.1.1.4.4788 . doi : 10.1007/3-540-45699-6_6 . ISBN  978-3-540-44044-4
  6. ^ a b c d e f Russo, Claudio V. (2008年10月27日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 53– 72. doi : 10.1145/1449955.1449770 .
  7. ^ Russo, Claudio V. (2008年10月23日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 5. doi : 10.1145/1449955.1449770 .
  8. ^ Russo, Claudio V. (2008年10月23日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 18. doi : 10.1145/1449955.1449770 .
  9. ^ a b cマランジェ、リュック;ル・フェッサン、ファブリス(2007 年 9 月 25 日)。「結合パターンのコンパイル」。ル・シェズネー・フランス。
  10. ^フルネ、セドリック;ゴンティエ、ジョルジュ。レヴィ、ジャン=ジャック。マランゲット、リュック (1996)。 「モバイルエージェントの計算」。CONCUR '96: 同時実行理論。コンピューターサイエンスの講義ノート。 Vol. 1119. Le Chesnay: 同時実行理論。 pp.  406–421土井10.1007/3-540-61604-7_67ISBN 978-3-540-61604-7
  11. ^ Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, A. (2003). 「JoCaml: 並行分散・モバイルプログラミング言語」.高度関数型プログラミング. コンピュータサイエンス講義ノート. 第2638巻. pp.  129– 158. doi : 10.1007/978-3-540-44833-4_5 . ISBN 978-3-540-40132-2
  12. ^ Conchon, S.; Le Fessant, F. (1999). 「Jocaml: Objective-Caml 向けモバイルエージェント」. Proceedings. 第1回および第3回エージェントシステム・アプリケーション・モバイルエージェント国際シンポジウム. pp.  22– 29. doi : 10.1109/ASAMA.1999.805390 . ISBN 0-7695-0342-X. S2CID  14355301 .
  13. ^ Odersky, Martin (2000年9月). 「関数型ネットの概要」.サマースクール, カミーニャ, ポルトガル, 2000年9月. 2395 .
  14. ^ Odersky, Martin (2000). 「関数型ネット」.プログラミング言語とシステム. コンピュータサイエンス講義ノート. 第1782巻. pp.  1– 25. doi : 10.1007/3-540-46425-5_1 . ISBN 978-3-540-67262-3
  15. ^ Itzstein, GS; Kearney, D. (2001). 「Join Java: Javaの代替並行性セマンティクス」.南オーストラリア大学技術報告書ACRC-01-001 .
  16. ^ベントン、ニック、カルデッリ、セドリック・フルネット (2002). 「C# のための最新の並行処理抽象化」. ECOOP 2002 — オブジェクト指向プログラミング. コンピュータサイエンス講義ノート. 第2374巻. pp.  415– 440. doi : 10.1007/3-540-47993-7_18 . ISBN 978-3-540-43759-8
  17. ^ Benton, N.; Cardelli, L. (2004). C# の最新の並行処理抽象化. ACM Transactions on Programming Languages and Systems . 第26巻.
  18. ^ Van Ham, Jurgen M.; Salvaneschi, Guido; Mezini, Mira; Noyé, Jacques (2014-04-22). 「JEScala: 宣言的イベントと結合によるモジュラーコーディネーション」 .第13回モジュラー性国際会議議事録. MODULARITY '14. ニューヨーク、ニューヨーク州、米国: Association for Computing Machinery. pp.  205– 216. doi : 10.1145/2577080.2577082 . ISBN 978-1-4503-2772-5
  19. ^ Singh, Satnam (2007年1月6日). 「STMを用いた結合パターンのための高階コンビネータ」 . p. 1.
  20. ^ a b Aaron, Turon; Russo, Claudio V. (2011年10月27日).スケーラブルな結合パターン(PDF) . ニューヨーク: Association for Computing Machinery. p. 4. ISBN 978-1-4503-0940-0
  21. ^ Aaron, Turon; Russo, Claudio V. (2011年10月27日).スケーラブルな結合パターン(PDF) . ニューヨーク: Association for Computing Machinery. p. 1. ISBN 978-1-4503-0940-0
  22. ^ a b Aaron, Turon; Russo, Claudio V. (2011年10月27日).スケーラブルな結合パターン(PDF) . ニューヨーク: Association for Computing Machinery. p. 3. ISBN 978-1-4503-0940-0
  23. ^ Aaron, Turon; Russo, Claudio V. (2011年10月27日).スケーラブルな結合パターン(PDF) . ニューヨーク: Association for Computing Machinery. p. 2. ISBN 978-1-4503-0940-0
  24. ^ a b cフルネ、セドリック。ゴンティエ、ジョルジュ。レヴィ、ジャン=ジャック。リュック・マランゲット。レミー、ディディエ (1996)。 「モバイルエージェントの計算」。CONCUR '96: 同時実行理論。コンピューターサイエンスの講義ノート。 Vol. 1119. Le Chesnay: 同時実行理論。 pp.  406–421土井10.1007/3-540-61604-7_67ISBN 978-3-540-61604-7
  25. ^ Maludzinski, Slawomir; Dobrowolski, Grzegorz (2007). 「分散結合計算におけるエージェント環境と知識」.マルチエージェントシステムとアプリケーション V.コンピュータサイエンス講義ノート. 第4696巻. pp.  298– 300. doi : 10.1007/978-3-540-75254-7_30 . ISBN 978-3-540-75253-0
  26. ^ Ma, Qin; Maranget, Luc (2004年4月5日). 「結合パターンにおけるパターンマッチングのコンパイル」. CONCUR 2004 - 並行性理論. コンピュータサイエンス講義ノート. 第3170巻. INRIA. pp.  417– 431. CiteSeerX 10.1.1.499.8443 . doi : 10.1007/978-3-540-28644-8_27 . ISBN  978-3-540-22940-7. S2CID  9956643 .
  27. ^ a b c Haller, Phillip; Van Cutsem, Tom (2008). 「拡張可能なパターンマッチングを用いた結合の実装」.コーディネーションモデルと言語. コンピュータサイエンス講義ノート. 第5052巻. ローザンヌ: コーディネーションモデルと言語. pp.  135– 152. CiteSeerX 10.1.1.210.1242 . doi : 10.1007/978-3-540-68265-3_9 . ISBN  978-3-540-68264-6
  28. ^ a b c Russo, Claudio V. (2008年10月23日). 「Visual Basicの結合パターン」. ACM SIGPLAN Notices . 43 (10): 53– 72. doi : 10.1145/1449955.1449770 .
  29. ^ a b c Sulzmann, Martin; SL Lam, Edmund. 「ガードと伝播機能を備えた並列結合パターン」デンマーク.
  30. ^ von Itzstein, G. Stewart; Kearney, David (2002). Join Java の応用. Proceedings of the Seventh Asia Pacific Computer Systems Architecture Conference ACSAC'2002. Melbourne, Australia, Australian Computer Society: 1-20: ACS.{{cite book}}: CS1 メンテナンス: 場所 (リンク)
  31. ^ Plociniczak, Hubert; Eisenbach, Susan (2010). 「JErlang: 結合機能を持つErlang」.コーディネーションモデルと言語. コンピュータサイエンス講義ノート. 第6116巻. Springer. pp.  61– 75. Bibcode : 2010LNCS.6116...61P . doi : 10.1007/978-3-642-13414-2_5 . ISBN 978-3-642-13413-5
  32. ^ Liu, Yigong (2007–2009). 「Join – 非同期メッセージ調整および並行処理ライブラリ」 .
  33. ^ 「ポリフォニック C# 入門」
  34. ^ 「Parallel C#」 。2013年11月26日時点のオリジナルよりアーカイブ
  35. ^ Hanus, Michael (2007年1月). The Joins Concurrency Library . Vol. 4354. Springer. ISBN 978-3-540-69608-7
  36. ^ 「コメガ」
  37. ^ Aaron, Turon; Russo, Claudio V. (2011年10月27日).スケーラブルな結合パターン(PDF) . ニューヨーク: Association for Computing Machinery. ISBN 978-1-4503-0940-0
  38. ^ Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, Alan (2003). 「JoCaml: 並行分散・モバイルプログラミング言語」(PDF) .高度な関数型プログラミング. コンピュータサイエンス講義ノート. Springer-Verlag. pp.  129– 158.
  39. ^ Hammond/Michaelson/Sun – Hume でのリアクティブシステムのプログラミング
  40. ^ 「Concurrent Basic」 。2015年4月25日時点のオリジナルよりアーカイブ
  41. ^ Russio, Claudio (2006). 「Joins同時実行ライブラリ」.宣言型言語の実践的側面. コンピュータサイエンス講義ノート. 第4354巻. ケンブリッジ: 宣言型言語の実践的側面. pp.  260– 274. CiteSeerX 10.1.1.187.8792 . doi : 10.1007/978-3-540-69611-7_17 . ISBN  978-3-540-69608-7
  42. ^ 「Joins 同時実行ライブラリ」
  43. ^ Haller, Phillip; Odersky, Martin (2007年6月). 「スレッドとイベントを統合するアクター」 .コーディネーションモデルと言語. コンピュータサイエンス講義ノート. 第4467巻. Springer. pp.  171– 190. doi : 10.1007/978-3-540-72794-1_10 . ISBN 978-3-540-72793-4
  44. ^ MONSIEUR、Geert (2010)、プロセスベースのサービス構成におけるパターンベースの調整、ベルギー、ルーヴェン: Katholiek Universiteit Leuven、p. 68
  45. ^ MONSIEUR、Geert (2010)、プロセスベースのサービス構成におけるパターンベースの調整、ベルギー、ルーヴェン: Katholiek Universiteit Leuven、p. 70