問題タブ [ioref]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - 並行プログラムにおける IORef 操作の並べ替えに関する推論
ドキュメントは言う:
並列プログラムでは、基になるプロセッサ アーキテクチャのメモリ モデルによっては、IORef 操作が別のスレッドに順不同で表示される場合があります...メモリ操作の並べ替えによって型が正しいコードが実行されないようにするために、実装が必要です。違う。特に、IORef から読み取った値を検査する場合、その値を作成したメモリ書き込みは、現在のスレッドの観点から発生している必要があります。
解析方法が完全にはわかりません。エドワード・ヤン言う
言い換えれば、「タイプセーフ違反がないことを除いて、並べ替えについては保証しません。」... 最後の文は、IORef が初期化されていないメモリを指すことは許可されていないことを述べています
だから... Haskell全体を壊すことはありません。あまり役に立ちません。メモリ モデルの例が発生した議論にも疑問が残りました (Simon Marlow でさえ少し驚いたようです)。
ドキュメントから明確に思われること
スレッド内では、
atomicModifyIORef
「以前の IORef 操作の前、または後の IORef 操作の後に発生することは決して観察されません」。ただし、ここでの「観察されない」という表現は、私が予期していなかった不気味な動作を暗示しています。少なくともデータの依存関係がない場合、Aは の
readIORef x
前に移動される可能性がありますwriteIORef y
readIORef x >>= writeIORef y
論理的には、次のようなものをどのように並べ替えることができるかわかりません
わからないこと
newIORef False >>= \v-> writeIORef v True >> readIORef v
常に戻りTrue
ますか?この
maybePrint
場合 (IORef ドキュメントから) (おそらく aまたは何かreadIORef myRef
と一緒に) 以前に並べ替えの障壁を強制したでしょうか?seq
readIORef yourRef
私が持つべき単純なメンタルモデルは何ですか? それは次のようなものですか:
個々のスレッド内および個々のスレッドの観点からは、IORef 操作の順序は正常で連続しているように見えます。しかし、コンパイラは、並行システムで特定の仮定を破るような方法で操作を実際に並べ替える場合があります。ただし、 スレッドが を実行すると、上
atomicModifyIORef
に表示された操作が後に発生することを観察するスレッドはありません 。逆もまた同様です。IORef
atomicModifyIORef
...?そうでない場合、上記の修正版は何ですか?
あなたの応答が「IORef
並行コードでは使用しないでください。使用しTVar
てください」である場合は、特定の事実と、.IORef
variables - 単純な Haskell IORef - 「タイプ `IO Int' と `Int' を一致させることができませんでした」 - どのように違うのかわかりません
変更可能な変数を格納するために、IORef を使用して Haskell で単純な乱数ジェネレーターを作成しようとしています。アイデアは、シードを初期化し、シードに基づいて数値を生成し、次のランダムな int 用に新しいシードを格納できるというものです。
私が得ている完全なエラーは次のとおりです。
タイプと一致しない方法がわかりません-randomGenがIntを受け取る/返すことを明示しています。これが私のコードです:
ここで何が起こっているのか分かりますか?
ありがとう、
更新されたコード:
haskell - IORef の使用と Control.Monad.Trans.Control の使用
経由でリクエストを行ったときにアプリケーションが見たリダイレクトのチェーンを調べられるようにしたかったのNetwork.HTTP.Client
です。
この機能は には組み込まれていませんが、(動作していない) サンプル コードを含むドキュメント のアイデアへの参照Network.HTTP.Client
がいくつかあります。既存の部品をほぼすべて再利用できるように思えたので、試してみることにしました。
グーグルで調べてみるとControl.Monad.Trans.Control
、スタック内にリクエストを蓄積するという私のニーズを満たすことができるようStateT [Request] IO
に思えましたが、数日間試してみてうまくいかなかった後、 ---を使用したばかりIORef
ですが、可変性に頼らずにこれを行うための巧妙な方法を見逃していないかどうか、まだ興味があります。
私の作業IORef
ベースのルーチンは次のようになります。
私の非動作 (リクエストが蓄積されないという点で)Control.Monad.Trans.Control
ベースのルーチンは次のようになりました。
問題は、私が見ているように、更新された状態をhandleRedirects
関数から返すことができないことです。これは、内部から呼び出されるためですhttpRedirect
。結果として、更新された値で restoreM を使用する機会がありません。どうすればこれらのものをうまく組み合わせることができるかわかりませんが、それは私の想像力や理解力の単なる失敗だと思います.
できるだけ簡単にするために、各バージョンで使用できるテスト ハーネスを次に示します。
haskell - 分岐した IORef リーダー関数がメイン スレッドを停止しているように見える
同時実行性とメモリの可視性についていくつかの実験を行っていたところ、この奇妙な動作に遭遇しました (インラインのコメントを参照)。
おそらくwriteIORef
子スレッドには見えないことを期待していましたが、メインスレッドが単に(明らかに)ストールすることはないと予想していました。
ghc 7.8.3 でコンパイル
そして一緒に走る
ここで何が起こっているのですか?
編集: 私のマシンには 2 つの実際のコアと 2 つのハイパースレッディング コアがあるため、+RTS -N
GHC では 4 つの機能が認識されます。Gabriel Gonzalez の回答に従って、次のことを試して、スケジューラが両方のスレッドを同じ物理プロセッサに配置していないかどうかを確認しました。
haskell - threepenny gui での IORef の使用
threepenny-gui で IORef を設定しようとしていますが、うまくいきません。私のアプリでは、IORef 自体はより複雑になり、それ自体は表示されませんが、この例は私が考える問題を示しています。
これが私の試みです:
コードの並べ替えは機能しますが、outValue は最新ではありません。
更新が時間どおりになるように修正するにはどうすればよいですか。また、コードの改善は大歓迎です。
ありがとう。
scala - IORef の正しいユースケースですか?
目標は、人に整数を入力してもらい、それが実際に整数であることを確認することです。そうでない場合は、もう一度尋ねてください。最初の試みはioMonad.whileMを使用することでした。これは実際には IO 内で値を返し、そのようなものを記述したためです (そうすれば、String を Int に「安全に」キャストできます)。
しかし、そのアプローチはうまくいきませんでした。なぜなら、この条件では、値を検証するだけでなく、コンソールからもう一度読み取ることもあるからです。
したがって、入力を読み取り、何らかの方法で条件に渡す必要があるため、IORefがまさに適切なツールである可能性があると考えていました (以前は使用したことがなかったので、関数型プログラミングを学ぶための謙虚な試みと考えてください)。 . 私はそれで終わった:
そして何が起こっているのか - 実際にはループ全体が完全に無視され、プログラムは最初の参照のある行に直接進みます:
では、ここでRefの概念を誤用しているのでしょうか。なぜ機能しないのですか?
ありがとう
更新: 実際には、このメソッドを書くことで最初の問題を解決しました:
その後whileMpropagating(askAndReadNumber)(_ forall notDigit)(ioMonad) map (_.toInt)
それでも、ここで IORef を利用することに興味があります。
Update2:私の残念なことにiterateWhile
、モナドではこれを正確に行います:)
haskell - Haste の StateT モナドのインターバル関数を書く
StateT
トランスフォーマーを Haste で正しくコンパイルできなかったため、独自の実装を作成しました。setInterval
私の状態モナド内でjavascriptを動かしたかったと思います。への ffi 呼び出しは次のとおりsetInterval
です。
m
に渡された後に backの結果を取得する方法は考えられませんでしたjsInterval
。ということで使ってみましたIORefs
。
元の状態を維持しているため、これは機能しませんでした。書き込みの前に読み取りが行われました。IORef
そのため、が書き込まれるまでループでポーリングする関数を作成しましたが、これは永遠にハングアップしました。
この機能を実装することは可能ですか?MonadEvent
forのインスタンスを書き込もうとしましStateT
たが、それも失敗しました。