12

まず、いくつかの背景。2 つの異なるモードのいずれかで操作したいキューが必要です。最初のモードでは、要素がキューに存在する場合は要素を取得できるようにしたいが、要素がない場合はブロックしたくない。2 番目のモードでは、キューに要素が含まれるまでブロックできるようにしたいと考えています。(各モードに特化したメカニズムを使用できることは承知していますが、いくつかの共通コードを除外したいので、両方の動作モードで同じメカニズムを使用できれば最も簡単です。)

を使用できますChanが、ドキュメントによると、isEmptyChanデッドロックの可能性があるため非推奨であるため、使用しないでください。これは私を残しますTChan。このtryReadTChan関数は、最初のモードに必要なものを正確に提供します (つまり、ブロックせずに要素が存在するかどうかを確認できます) が、何が機能するのか正確にはわかりreadTChanません。私のメンタル モデルはatomically、要素がチャネルに存在するまでブロックが再試行し続けるというものです。これは、CPU サイクルを浪費するビジー ループになることを意味します。これはreadChan、MVar がランタイム スレッド スケジューラによって理解されるため、要素が利用可能になるまでスレッドの実行を実際にブロックする (正しく理解できれば) (つまり、非 STM バージョン) とは異なります。

つまりTChan、ランタイムChanを使用readTChanすると、値が利用可能になるまで呼び出し元のスレッドをスケジュールしないほどスマートであるということですか? それとも、値が到着するまで継続的にポーリングするために多くの CPU サイクルを無駄にしますか?

4

2 に答える 2

15

STMブロッキング(via retry)は、トランザクションをすぐに再試行するかのように動作しますが、実装はよりスマートです。STMは、トランザクションの進行中に読み取った変数を追跡するため、トランザクションが同じように動作することを認識しています。これらの変数の値は同じです。したがって、トランザクションが失敗すると、使用した変数の1つが変更されるまで、トランザクションはブロックされます(実際には再試行されません)。sの場合、TChan誰かがに書き込むまでブロックされることを意味しますTChan

STMの優れた紹介として、同時および並列のHaskellに関するSimonMarlowのスライドをお勧めします(とりわけ)。

于 2013-01-27T07:49:06.577 に答える
11

あなたのメンタルモデルは正しい表示的意味論を持っていますが、STMが行う運用上の最適化を見逃しています。TVarトランザクションがSTMで再試行すると、再試行が変更される前に読み取ったトランザクションがブロックされるまでブロックされます。(そして、はい、TChanの観点から実装されていTVarます。)

したがって、トランザクションの実行は、トランザクションが継続的に再試行されている場合と同じ意味ですが、STMシステムは、トランザクション内で状況が異なる可能性がない場合にビジーループを発生させないほどスマートです。

于 2013-01-27T07:47:13.457 に答える