オズの玠晎らしい囜、たたはsendを䜿甚しおデヌタを受信する方法

かなり前に、䞊列プログラミングツヌルに関する情報を収集しお、゚レガントな぀たり、感芚を衚珟するのが難しい蚀語Oz http://www.mozart-oz.orgに出䌚いたした。 この蚀語は、Habraコミュニティに導入するに倀するように思えたした。 そしお、それをする時間ず理由がありたした。

Ozはマルチパラダむムプログラミング蚀語です。 蚀語の基本的な抜象化のセットは珍しく、たずえば、情報を送信する送信プロシヌゞャを䜜成しお、その助けを借りおデヌタを受信するこずもできたす。 そしお、キャッチなしで

send(socket; buffer; flag) = (if (flag == RECV) (recv(socket; buffer)) or (realsend(socket; buffer))) 。

デヌタの送信ず受信は、Oz仮想マシンの同じ操䜜シヌケンスによっお実行されるのはたさに事実です。 圓然、これは、デヌタおよび䞊列プロセスを操䜜するための特別な抜象化によっお実珟されたす。 私の意芋では、これらはOzの特城を非垞によく感じるこずができるので、このテキストはこれらの抜象化の説明に専念しおいたす。 もちろん、オズは以䞋に述べるもの以䞊のものですが、私には、toなセンドの秘密はこの蚀語を初めお知り、それを楜しむのに適した玠材であるようです。



0.はじめに


Portコンストラクトを実装するプログラムのテキストから始めるこずができたす。これは、sendプロシヌゞャを䜿甚しおデヌタが送信されるずきに送信されたす。 Portの䜿甚䟋は、同じプログラムに含たれおいたす。 ゜ヌスコヌドこのテキストの固有名

 
	ポヌトを宣蚀する 
	 
	ロヌカルPortTag NewPort IsPort 
		 PortTag = {NewName} 
	 
		楜しい{NewPort FS} 
			ロヌカルSC 
				 C = {NewCell S} 
				 FS = !! S 
				 {NewChunkポヌトPortTagC} 
			終わり 
		終わり 
	 
		楜しい{IsPortP} 
			 {Chunk.hasFeature P PortTag} 
		終わり 
	 
		 proc {PMを送信} 
			地元のMsさん 
				 {Exchange P.PortTag Ms Mr} 
				 Ms = M |  !! Mr 
			終わり 
		終わり 
	 
		ポヌト=ポヌト 
		  
			新芏NewPort 
			 isIsPort 
			送信送信 
		  
	終わり 
	 
	 NewQueueServerを宣蚀する 
	 
	 fun {NewQueueServer} 
		䞎えられたギブポヌトのロヌカル 
			 GivePort = {Port.new Given} 
			 TakePort = {Port.new Taken} 
	 
			 proc {Jos Xs Ys} 
				ロヌカルXr Yr XY in 
					 Xs = X |  Xr 
					 Ys = Y | 幎 
					 X = Y 
					 {Xr Yrに参加} 
				終わり 
			終わり 
	 
			スレッド{Join Given Taken}終了 
		 
			埅ち行列 
			  
				 putproc {$ X} {Port.send GivePort X} end 
				 getproc {$ X} {Port.send TakePort X} end 
			  
		終わり 
	終わり 
	 
	 Qを宣蚀する 
	 
	スレッドQ = {NewQueueServer}終了 
	 
	 {Q.put 1} 
	 {{Q.get $}を参照} 
	 {{Q.get $}を参照} 
	 {Q.put 2} 


ご芧のずおり、キャッチはありたせん。 䞡方のqueueserver関数-putおよびget-は、名前に察応するセマンティクスを持぀Sendプロシヌゞャを䜿甚しお実装されたす。 このコヌドは短くなる可胜性がありたす-Ozでは構文の砂糖で十分であり、必芁な説明の量を枛らすために䞊蚘では䜿甚されおいたせん。

このコヌドがどのように機胜するかを理解するには、1Ozプログラム実行のモデルを扱う必芁がありたす。倉数、スレッド、アラむメント挔算子 = ; 2手順。 3セルセル、メモリの領域チャンクおよび将来未来。

1.倉数、スレッド、挔算子=


前述のずおり、Ozはマルチパラダむム蚀語です。 りィキペディアでは、機胜的、論理的、呜什的、オブゞェクト指向、分散、䞊列䞊行ずいう意味で、および制限付きプログラミング甚の蚀語ずしお蚘述されおいたす。 しかし、それは別のパラダむム-デヌタフロヌを䜿甚したプログラミングデヌタフロヌプログラミングに基づいおいたす。 Ozは、デヌタストリヌムを䜿甚したコンピュヌティングの元のCPUアヌキテクチャで䜿甚される抂念に非垞に近いこのパラダむムを実装し、次のように実行したす。

1.1。 Ozでのすべおの蚈算は、ストアに含たれるデヌタを䜿甚しお行われたす。 同時に、ストレヌゞは非垞に抜象的であり内郚の仕組みはプログラマヌから隠されおおり、ストア内の情報は特定のむンタヌフェむスを介しおのみ制埡できたす、分散されおいたすOzコンピュヌティングのすべおの参加者は、ネットワヌク䞊に散圚するものも含めおストアで䜜業できたす ストアは、3぀の異なる方法で情報を保存できたす。 1自由たたは関連する論理倉数の圢匏。 2メモリのセルではなく、倉数ぞの名前付き可倉ポむンタである可胜性が高いセルの圢匏。 3Ozでクロヌゞャず呌ばれるプロシヌゞャの圢匏圓然、これらは1次オブゞェクトです。぀たり、プログラムで明瀺的に操䜜できたす。

1.2。 蚈算は、スレッドが実行されるずきに行われたす。 同時に、Ozのスレッドはデヌタフロヌです。 ぀たり、特定の䞀連のステヌトメントステヌトメントが次々に実行されたすすべお呜什型蚀語のようにが、1぀の譊告がありたす。挔算子は、䜿甚されるすべおの倉数が接続されおいる堎合にのみ実行されたす。 それ以倖の堎合、スレッドは䞀時停止し、必芁な倉数をバむンドする瞬間を埅ちたす。 実際、䜿甚されるデヌタの準備が敎ったずきに特定の挔算子を実行するこずが、日付フロヌ蚈算の䞻な方法です。

Ozでのスレッドの䜜成は、 thread ... end構文を䜿甚しお非垞に簡単です。 これはfork()スタむルで䜜成されたす。 ぀たり、生成されたスレッドは、 thread ... end操䜜の時点で芪スレッドが䜿甚できたすべおの倉数぀たり、倉数にアクセスできたす。

1.3。 Ozの倉数は論理的です。

Ozスタむルのブヌル倀は、別の倉数ず同䞀芖できる1回バむンドされた倉数です。

䞀般に、この定矩マニュアルからの翻蚳はOzの倉数に぀いおほずんど述べおいたせん。 圌らはあなたがあなた自身でもう少しできるようにしたす。 たた、通垞のc / javascript / haskell倉数ずは倧きく異なりたす。倉数は、名前付きメモリセルc / jsたたは名前付き倀haskellです。 おそらくOzの倉数の最良のアむデアには、いく぀かの技術的な詳现の説明が䞎えられたす。

1.3.1。 Ozの倉数のラむフパスは、 local ... in ... endたたはdeclare ... in ...構文を䜿甚しお宣蚀されおいるずいう事実から始たりたす。 これらの構造の違いは、 local ...ではin ... end内の操䜜でのみ䜿甚する倉数を宣蚀でき、declareで宣蚀された倉数は、察応するin埌のすべおの堎所で䜿甚できるこずです。 圓然、 declareは、モゞュヌルのグロヌバルスコヌプでのみ倉数を定矩するために䜿甚できたす。

倉数の宣蚀は、ストア内に新しいノヌドが䜜成され、宣蚀された倉数が参照するこずです。 たた、 unknown倀がノヌドに曞き蟌たれ、倉数がデヌタに関連付けられおいないこずが瀺されたす。 スレッドがデヌタに察しおそのような倉数を呌び出すず、察応するノヌドがデヌタに関連付けられるたで、スレッドは䞭断されたす。 䟋コヌド1

 
	ロヌカルX 
		スレッド{Browse 2 * X} end 
		 X = 5 
	終わり 


Browseは、匕数を出力する暙準のOzルヌチンの1぀です。 この䟋でX宣蚀されるず、倉数が䜜成され、ストア内の察応する新しいノヌドが䜜成されたす。 BrowseがXを介しおこのノヌドにアクセスするず、察応するXノヌドに倀が衚瀺されるたで、察応するスレッドの実行が䞭断されたすノヌドの倀ずノヌドぞの倉数のバむンドの䞡方がここで倉曎できたす。

1.3.2。 ノヌドの倀は、統合統合たたは別の名前増分再カりント増分テルのプロセスに配眮されたす。 匏のペアの統䞀は、 = 等号挔算子挔算子によっお行われたす。 同じプロセスで、ノヌドぞの倉数のバむンドも倉曎できたす。 コヌドE1 = E2の匏のペア匏の堎合の統合アルゎリズムは、このように機胜したすE1およびE2の可胜性のあるオプションの分析を䌎う再垰的手順。

U.1。 蚈算E1およびE2の結果は、原子型Ozの倀です原子は䞍可分な型です敎数、浮動小数点数、リテラル-文字列など。 この堎合、これらの倀が等しい堎合、挔算子が実行され、䞍等匏が満たされるず、䟋倖がスロヌされたすOzの䟋倖はかなり暙準的であり、 try ... catch ... finally ... end ; finally -optionalを䜿甚しお凊理されたす。

U.2。 E1の蚈算結果は倉数であり、 E2の蚈算結果は䜕らかのタむプの倀ですこの状況ず察称的なのは、 E1蚈算が䜕らかのタむプの倀になり、 E2が倉数になるこずです。 次のようになりたす。

 
	 X =Y + Z* 5 


この堎合、すべおが次のように機胜したす。

U.2.1。 E1によっお蚭定された倉数は、䞍明なノヌドを参照しおいたす。 その堎合、 E2蚈算によっお埗られた倀がこのノヌドに曞き蟌たれ、その結果、 E2倉数が接続されたす。

U.2.2。 E1倉数がすでにアトミック倀に関連付けられおいる堎合、察応するノヌド内の倀がE2倀ず比范され、タむプたたは倀自䜓が䞀臎しない堎合、䟋倖がスロヌされたす。 それ以倖の堎合、ステヌトメントは終了したす。

code-1から倉数Xをバむンドするのはこのルヌルです。 倀5に関連付けられた埌、呌び出されたプロシヌゞャBrowse内でこのバむンディングを埅機する挔算子が実行されたす。 そしお、コヌド-1が次のようになった堎合、結果はたったく同じになるこずは明らかです。

 
	ロヌカルX 
		スレッド{Browse 2 * X} end 
		 5 = X 
	終わり 


U.2で。 E1-倉数が耇合型の倀に関連付けられおいる堎合、別のオプションが可胜ですが、埌でU.4段萜で怜蚎されたす...

U.3。 E1ずE2䞡方が䜕らかの倉数を定矩したす。 可胜なオプションもありたす。

U.3.1。 倉数の1぀がバむンドされおいないか、䞡方の倉数がバむンドされおいないこずがわかりたす぀たり、倀が䞍明なノヌドを参照しおいたす。 この堎合、関係のない倉数の1぀のノヌド、たたは接続されおいない倉数の䞍明なノヌドは砎棄されたす。 次に、このノヌドを以前に参照した倉数が倉曎され、他の倉数ず同じノヌドを参照し始めたす。

code-2を実行するこずにより、なぜここで既に明確になっおいるはずです。

 
	ロヌカルXYZ 
		スレッド{Browse X + Y + Z} end 
		 X = Y 
	 Z = X + YX = 10 
		 X + Y = Z 
	終わり	 


Ozの倀は40になりたす。たた、コメントを削陀するず %始たるOzが「フリヌズ」したす。

U.3.2。 䞡方の倉数は、倀が曞き蟌たれるノヌドを参照したす。 この堎合、動䜜は次のずおりです。 これらが異なるタむプの倀である堎合、たたは同じタむプの異なるアトミック倀である堎合、䟋倖がスロヌされたす。 これらがアトミックタむプの等しい倀である堎合、オペレヌタヌは実行を完了したす。 ただし、ノヌドは耇合型の倀を栌玍するこずもできたす。

Ozの䞻芁な耇合型はレコヌドです。 構文的には、゚ントリは次のようになりたす。

 
	ラベルfeature0field0 feature2field2 ... featureNfieldN 


おおよそ、䞊蚘は閉じられたレコヌドであるため、フィヌルドフィヌルドの数は固定されおおり、レコヌドも開いおいたす。 レコヌドフィヌルドには、察応するプロパティ機胜の名前で、ドットを介しおアクセスできたす。 構造内のフィヌルドの数は、アリティず呌ばれたす。 より具䜓的な䟋

 
	 U = habrauserニックネヌム 'ミカノむド'カルマ10匷床10 
	 K = U.karma 


埮劙レコヌドタむプの倀自䜓のフィヌルドはOz倉数です。 䞊蚘の䟋では、レコヌドタむプずhabrauserラベルを䜿甚しお倀を䜜成するず、蚘述されたアルゎリズムに埓っおアトミックタむプ倀で統合された3぀の倉数が䜜成されたす 'mikhanoid'、10および10。ただし、そのような倀の代わりに、倉数フィヌルドを任意の匏で統合できたす。 この時点で、このコヌドがどのように機胜するかが明確になるはずです。

 
	地元のUKS 
 *U = habrauserニックネヌム 'ミカノむド'カルマK匷床S 
		 K = s 
		 10 = K 
	終わり 


行*では、非バむンド倉数U U.2.1ルヌルに埓っおレコヌドタむプ倀U統合されおいたす。

Ozレコヌドには重芁な圹割がありたす-それらはストアを有向グラフ構造に倉換したすノヌドがタむプレコヌドの倀を栌玍する堎合、その倉数フィヌルドは他のノヌドを指したす。 たた、蚘茉されおいるアルゎリズムは、U.4。のおかげで、グラフマヌゞアルゎリズムず芋なすこずができたす。

U.4。 ここでは、1匏E1ずE2䞡方がレコヌドタむプの倀である、2レコヌドが栌玍されるノヌドを参照する倉数を定矩する、3 E1 、 E2いずれかがレコヌドタむプの倀を蚭定する、 another-レコヌドが保存されおいるノヌドに関連付けられた倉数を蚭定したす。 これらのすべおの堎合、゚ントリにa異なるラベル、たたはb異なるアリティ、たたは©異なるプロパティセットがある堎合、䟋倖がスロヌされたす。 レコヌドがポむントa、b、および©で䞀臎する堎合、異なるレコヌドの倉数のペアは同じプロパティ名で統合されたす。

この時点で、そのようなコヌドの䜜業の結果ずしお、理由がすでに明確になっおいるはずです。

 
	ロヌカルWXYZ 
		 W = XZ = Y 
		 fa10 bX= faY b20 
		 {W + Zを参照} 
	終わり 


倀30が衚瀺されたす。

別の興味深い䟋はこのコヌドです

 
	ロヌカルZ 
		 Z = fZ 20 
		 {Zを参照} 
	終わり 


ここで、 fは、フィヌルドのプロパティが1からそのアリティたでの敎数名を自動的に取埗するレコヌドの倉圢です。 Ozでは、そのようなレコヌドはタプルず呌ばれ、論理プログラミングの耇合語の類䌌物です。 䞊蚘のコヌドでは、次のこずが起こりたす。 1タむプrecordの倀は2぀のフィヌルドで䜜成されたす。぀たり、2぀の倉数が䜜成されたす。 2プロパティ1フィヌルド1 、無関係な倉数Z、20の原子倀を持぀2番目のフィヌルドず統合されたす。その結果、 fの倀は、倉数Zおよび倀20を栌玍するノヌドを指す未知のノヌドを指したす。 Z指すノヌドにはレコヌドタむプの倀が曞き蟌たれ、その2番目の芁玠倉数Zなどはこのノヌドを指したす。 特別なこずは䜕もありたせん。ストアグラフにルヌプがありたす。 Browseは、 R10 = f(R10 20)たす。

Ozのリストは䞀皮のタプルです。 それらは機胜的および論理的プログラミングのために暙準的に線成されおいたす。リストはタプルであり、最初の芁玠は倉数の先頭で、2番目は末尟を構成するリストです。 リストの末尟の頭を指定するには、蚘号|䜿甚したす|  Head | Tail Head | Tail

2.手順


Ozでは、プロシヌゞャを䜿甚しおステヌトメントのシヌケンスを抜象化できたす。 Ozのプロシヌゞャは倀ファヌストクラスオブゞェクトであるため、倉数に自由に「割り圓おる」こずができたす。 より詳现に。 Ozは、䜕らかのコヌドずしおストアにプロシヌゞャを実装するクロヌゞャヌを栌玍したす。 このような各閉鎖手順は、ストア党䜓の䞀意の名前を取埗したす。 Ozの名前はリテラル-原子型の倀です。 プロシヌゞャコヌドを䜜成し、䞀意の名前を割り圓おた埌、名前はいく぀かの倉数が参照するノヌドに曞き蟌たれたす。 その埌、この倉数を介しおプロシヌゞャを呌び出すこずができたす。

そのため、゜ヌスコヌドでは、 NewPort 、 IsPort 、 Send 、...がlocalたたはdeclareを䜿甚しお倉数ずしお宣蚀されおいたす。

プロシヌゞャを定矩する基本的な構成䜓はprocです。

 
	ロヌカル... P ... in 
		 ... 
		 proc {P X1 ... XN} S1 ... SM終了 
		 ... 
	終わり 


X1 、...、 XNは正匏な匕数です。 S1 、...、 SMは、プロシヌゞャを実装する䞀連の挔算子です。 プロシヌゞャは、䞭括匧を䜿甚しお呌び出されたす。

 
	 {P A1 ... AN} 


A1 、...、 ANは実パラメヌタです匏、倉数など。 呌び出しは、仮パラメヌタに察応する新しい倉数の宣蚀で発生したす。仮パラメヌタは匕数ず統合されおおり、その䞭には無関係の倉数が存圚する堎合がありたす。 したがっお、プロシヌゞャは、任意のパラメヌタを介しおデヌタを受信および返すこずができたす。 したがっお、コヌドの可読性を高めるために、プログラマヌが倀を返すためだけに䜿甚するこずを期埅する倉数は、接頭蟞でマヌクできたす? これは単なるコメントです。

プロシヌゞャの名前を栌玍するノヌドに関連付けられた倉数は、次の䟋のように、匏を評䟡した結果になる堎合もありたす。

 
	 {Q.put 1} 


Ozには匿名プロシヌゞャを䜿甚する機胜がありたすが、これは通垞ずは異なる方法ネストメカニズムを䜿甚で実装されおいたす。 {...}囲たれた䞀連の挔算子では、䜍眮の1぀がシンボル$ -添付ファむルのラベルで占められおいる堎合がありたす。 Ozが䞭括匧内でこのようなマヌクに遭遇し、䜕らかの挔算子を実行するず、1 {... $ ...}数だけ新しいロヌカルスコヌプに新しい倉数を自動的に䜜成し、このスコヌプに2 {... $ ...}呌び出し、マヌカヌの代わりにこの呌び出しを新しい倉数に眮き換え、3これらの倉数を実行可胜ステヌトメントの{... $ ...}堎所に挿入したす。 䟋えば

 
	ロヌカルP in 
		 proc {PXY} Y = X + 10 end 
		 {{P 20 $} + {P 30 $} + 40を参照} 
	終わり 


ずしお実行されたす

 
	ロヌカルP in 
		 proc {PXY} Y = X + 10終了 
		ロヌカルX1 X2 
			 {P 20 X1} 
			 {P 30 X2} 
			 {X1 + X2 + 40を参照} 
		終わり 
	終わり 


ネストマヌクは{...}内の最初の堎所でも䜿甚できたすが、プロシヌゞャの定矩䞭のみです。 ただし、接続メカニズムはたったく同じように機胜したす。 コヌド

 
	ロヌカルP in 
		ロヌカルP1 
			 proc {P1 X1 ... XN} S1 ... SM終了 
			 P = P1 
		終わり 
	終わり 


そしお

 
	ロヌカルP in 
		 P = proc {$ X1 ... XN} S1 ... SM゚ンド 
	終わり	 


同等です。

Oz関数もプロシヌゞャであり、プロシヌゞャが確実に倀を返さなければならないこずがわかっおいる堎合の構文の簡略化です。 次に、1぀の仮パラメヌタヌの説明を保存できたす。぀たり、 fun {F X1 ... XN} S1 ... SM end proc {F X1 ... XN Y} S1 ... Y = SM endず同じproc {F X1 ... XN Y} S1 ... Y = SM endたす。 呌び出し{F A1 ... AN} 、関数ずしお、Ozは自動的にプロシヌゞャ{F A1 ... AN $}呌び出しに倉わりたす

たずえば。

 
	楜しい{FX} 
		ロヌカルK 
			 K = X / 20 
			 {Kを参照} 
		終わり 
		ロヌカルL 
			 L = 30 
			 X == L 
		終わり 
	終わり 


定矩を満たしおいる

 
	 proc {FXY} 
		ロヌカルK 
			 K = X / 20 
			 {Kを参照} 
		終わり 
		 
		 Y =ロヌカルL 
			 L = 30 
			 X == L 
		終わり 
	終わり 


この堎合、 local ... in ... endブロックの倀は、その䞭の最埌のステヌトメントの倀です。 ぀たり、この䟋では、 Fは、質問に察する答えを埗るための呌び出しの結果になりたす。関数30の最初で唯䞀の匕数は等しいです。

3.セル、メモリ領域チャンク、および将来将来


ストア内のデヌタを凊理するために、Ozはさらにいく぀かの抜象化をサポヌトしおいたす。

3.1。 ストレヌゞ領域は、ストア内の゚ントリの䞀郚です。 ただし、通垞のレコヌドずは異なり、それらは䞀意の名前を䜿甚しお識別され手順ず同様、アリティを刀別するこずはできたせん。 ぀たり、それらのコンポヌネントには、プロパティ名機胜によっおのみアクセスできたす。 これらの名前がコヌドの䞀郚から隠されおいる堎合、これらの領域では、察応するメモリ領域の芁玠ぞのアクセスは䞍可胜になりたす。 ゚リアは、 {NewChunk Record}関数を呌び出すこずで䜜成されたす。 呌び出しは、䞀意の名前でメモリ領域を䜜成し、その名前を返したす。 名前は、䜕らかの倉数によっお参照されるノヌドに曞き蟌むこずができたす。 次に、この倉数ず挔算子を䜿甚し. メモリ領域のフィヌルドにアクセスできたす

 
	ロヌカルXR 
		 R = fa1 b2 c3 
		 X = {NewChunk R} 
		 {Xcを参照} 
	終わり 


3.2。 Ozのセルは、状態で動䜜するように蚭蚈されおいたす。 ストア内のプロシヌゞャおよびメモリ領域ずしおのセルは、䞀意の名前で定矩されたす。 倉数ず同様に、それはあるノヌドぞのポむンタですが、倉数ずは異なり、セルが指すノヌドは明瀺的に繰り返し蚭定できたす。 セルは次のむンタヌフェヌスを定矩したす。

C = {NewCell E}-匏Eず倉数の倀の統䞀から生じるノヌドを指すセルを䜜成したす-手続きの仮匕数NewCell。新しく䜜成されたセルの新しい䞀意の名前が返され、倉数に割り圓おられたすC。セルからノヌドぞのリンクは、もちろん、ガベヌゞを収集するずきに考慮されたす。{IsCell C}質問に答えたすはCセル名に関連付けられた倉数です。

@C-結果ずしおのこの匏には、倉数に栌玍された名前のセルが参照するノヌドを指す倉数がありたすC。C := E名前が栌玍されおいるセルのポむンタを倉曎したす。Cその結果、関係のない名前のない倉数ず匏の結果の統合の結果ずしお埗られたノヌドを指したすE。

{Exchange C E1 E2}-䞍可解な1぀のアトミック操䜜は@C、E1ず統合され、実行されC := E2たす。

たずえば、セルはカりンタヌずしお䜿甚できたす。

 
	ロヌカルC 
		C = {NewCell 0} 
		{Exchange CXスレッドX + 1終了} 
	終わり 


ここで排陀できたせんthread ... end。そしお、これは、実行䞭の各スレッドに察しお、Ozが最埌のスレッド本䜓挔算子ず統合される非バむンド倉数を自動的に䜜成するずいう理由で機胜したす。そしお、この䟋のこの倉数は最埌の匕数Exchangeです。

3.3。将来のものは最初にSmalltalk-72で提案され、その埌、それらのアプリケヌションのアむデアはMultiLISP1985で開発されたした。 Futureは、かなり䞀般的なツヌルです。Javaにあり、java.util.cuncurrent.Future; からアクセスできたす。それらのサポヌトはC ++ 0xで蚈画されおいたす。それらはOzでサポヌトされおいたすが、珍しい圢匏です。

䜕らかの匏の未来Eは、非同期コンピュヌティングに関連するオブゞェクトEです。将来的には、未確定の結果を䌎ういく぀かの操䜜が可胜になりたす。E-たずえば、関数呌び出しで䜿甚したり、リストに曞き蟌んだり、他の非同期蚈算に枡したりしたす。䜜業を継続するために必芁なのが匏の倀である堎合、Eその未来ぞのアピヌルEは、蚈算されるたで実行を䞀時停止したす。

Ozでは、通垞の倉数には同様のプロパティがありたす。倉数のあるアクションは、参照するノヌドに倀が珟れるたで埅たずに実行できたす。すでに瀺した䟋の倚くはこれを瀺しおいたす。ただし、Ozの倉数は情報亀換の双方向チャネル=です。匏の巊右に立぀こずは、統合アルゎリズムに察しお察称的です。したがっお、コヌド内では

 
	ロヌカルX 
		スレッドX = 5終了 
		スレッドX = 7終了 
		X = 3 
		{Xを参照} 
	終わり 


デヌタを生成するスレッドずしお目立぀ものはありたせん。統合プロセスの䟋倖により、スレッドが発生する可胜性がありたす。将来は、この状況で䜕らかの秩序を確立するこずができたす。Ozでは、将来はノヌドぞの読み取り専甚リンク、぀たり倉数の倚少制限されたバヌゞョンです。未来が統合プロセスに参加する堎合、このプロセスは未来に察応する倉数が接続されるたで䞭断されたす。XOzの倉数の将来は、挔算子によっお圢䜜られ!!Xたす。䞊蚘の䟋の順序は、たずえば次のように入力できたす。

 
	ロヌカルXY 
		Y = !! X 
		スレッドY = 5終了 
		スレッドX = 7終了 
		Y = 3 
		{閲芧Y} 
	終わり 


ここでは、倀は垞に2番目のスレッドでのみ圢成されたす。

4.すべお䞀緒に


このテキストを最初にスクロヌルする必芁がないように、導入郚からコヌドを再び持っおくるず䟿利です。

 
00 declare Port in 
01	 
02 local PortTag NewPort IsPort Send in 
03 PortTag = {NewName} 
04	 
05 fun {NewPort FS} 
06 local SC in 
07 C = {NewCell S} 
08 FS = !!S 
09 {NewChunk port(PortTag: C)} 
10 end 
11 end 
 12	 
13 fun {IsPort ?P} 
14 {Chunk.hasFeature P PortTag} 
15 end 
 16	 
17 proc {Send PM} 
18 local Ms Mr in 
19 {Exchange P.PortTag Ms Mr} 
20 Ms = M | !!Mr 
21 end 
22 end 
 23	 
24 Port = port 
25 ( 
26 new: NewPort 
27 is: IsPort 
28 send: Send 
29 ) 
30 end 
 31	 
32 declare NewQueueServer in 
 33	 
34 fun {NewQueueServer} 
35 local Given GivePort Taken TakePort Join in 
36 GivePort = {Port.new Given} 
37 TakePort = {Port.new Taken} 
 38	 
39 proc {Join Xs Ys} 
40 local Xr Yr XY in 
41 Xs = X | Xr 
42 Ys = Y | Yr 
43 X = Y 
44 {Join Xr Yr} 
45 end 
46 end 
47	 
48 thread {Join Given Taken} end 
 49		 
50 queue 
51 ( 
52 put: proc {$ X} {Port.send GivePort X} end 
53 getproc {$ X} {Port.send TakePort X} end 
54 
55終わり 
56終わり 
 57	 
58でQを宣蚀する 
 59	 
60スレッドQ = {NewQueueServer}終了 
 61	 
62 {Q.put 1} 
63 {{Q.get $}を参照} 
64 {{Q.get $}を参照} 
65 {Q.put 2} 


プログラム党䜓を行ごずに蚘述するこずは意味がありたせんが非䞊列プログラムでさえもどのように機胜するかに぀いおはほずんどわかりたせん、いく぀かの点を明確にする必芁がありたす。

4.1。䜜成Port。

Portレコヌドを衚し、フィヌルドは䞀連のプロシヌゞャに関連付けられたす。これは、いく぀かの手順を䟿利にグルヌプ化したものに過ぎたせん。ポヌト自䜓は、関数によっお䞀意性が保蚌されおいる名前の䞋のセルを含むメモリ領域NewNameです。倉数はPortName、ロヌカルナニット02から30に衚瀺されおいるので、あなたは、メモリ領域のコンポヌネントにアクセスできる唯䞀の手順IsPort、NewPort、Send。このブロックの倖でPortNameは、倉数に぀いお䜕も知られおいないため、ポヌトの状態を保存するメモリ領域のフィヌルドぞのアクセスはほずんどありたせんもちろん、名前は掚枬できたすが、このメカニズムはカプセル化には十分です。

機胜に泚意を払う必芁がありたすNewPort05-11。ポヌトメモリ領域自䜓を返すこずに加えお、匕数は、その最初の匕数を通じお、セルを初期化するfuture倉数も返したす。これは、初期化GivenずTaken36-37に䜿甚されたす。

4.2。手順Send17-22。

ポヌトメモリ領域のセルは、垞に䞍明なノヌドを指しおいるこずに泚意しおください。そしおSend、次の呌び出しで保蚌される最初のこずは、前のノヌドぞのリンクが倉数Msに入力され、その代わりに、非バむンド倉数のノヌドぞのリンクを配眮するこずですMr。次に、Send倉数の倀が圢成されたすMs。これは、リストタプルずの統合䞭に取埗され、送信されたメッセヌゞ関連しおいない可胜性がありたすが最初の堎所にあり、未来が2番目にありたすMr再びリストは2番目のタプルです䜕でも我慢できたす。埌続の呌び出しSendは、倉数で同じこずを行いたすMr、およびこのプロセスは、セルを初期化するために䜿甚された倉数を埐々にに倉え、NewPortその将来が倖郚に返されお、リストに倉えたす。蚀い換えれば、Send実際にキュヌでメッセヌゞを送信したす。

4.3。手順Join39-46。

ここで最も重芁なこずは、この手順が適甚される察象であり、別のスレッドで動䜜したす48。これはずに適甚されGiven、Taken呌び出しの結果ずしおSend埐々にリストに倉わりたす。実際のパラメヌタヌJoinは垞に未来であるため、結合挔算子41-42はバむンド埌にのみ実行されXs、Ysで発生しSend、これらの倉数をタプルを衚瀺するリンクに倉換したすMessage | SomeFuture。その埌Message、着信Givenおよび発信Takenフロヌのコンポヌネントが統合され、Join 将来のリストの末尟に呌ばれたす量子力孊に少し䌌おいたすよねアむンシュタむンは、隠された倉数で宇宙のモデルを構築するための䞊列プログラミングの知識を欠いおいたのでしょう。

4.4。 最埌に。

バむンドされた倉数をGiven䜿甚しおストリヌムに蚭定されたSend倉数は、スレッド48でストリヌムに蚭定された察応するバむンドされおいない倉数ず統合されたすTaken。もちろん、状況は完党に察称的であり、そしお名前putずはget䟿宜䞊䜿甚されおいたす。ただし、キュヌサヌバヌはただ非同期であり、䟿利です。

5. Ozのその他の興味深い機胜


Ozは他の機胜およびそれらの倚くは広倧ですの䞭でも特に興味深い䞊列プログラミングモデルを提䟛したす。Prologで採甚されおいる叀兞的なものずは異なりたす。たずえば、プログラマヌがオプションを怜玢および列挙するための独自の手順を定矩できるずいう点です。そしお、もちろん、Ozが採甚しおいる論理プログラミングモデルは䞊行しおいたす。

Source: https://habr.com/ru/post/J63715/


All Articles