問題タブ [stm]
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.
memory - Clojure STM のメモリ不足
STM を使用して並列銀行振込を実行する小さなプログラムがあるため、2 コアと 1 コアの異なるマシンでテストしています。2 コア マシンではすべてが機能しますが、1 コア マシンでは、100 万の並列トランザクションを実行すると Java Out of Memory エラーがスローされます。
エラーは次の "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space です
また、同じプログラムのJava同期バージョンがありますが、遅くても100万回のトランザクションに達する可能性があります。
Clojure アプリケーションを 1 コア マシンで動作させるにはどうすればよいですか? 残念ながら、ガベージ コレクターはそれほど多くの Ref を処理できません...どう思いますか?
助けてくれてどうもありがとう!
更新:
それは今動作します, 私はjava -Xmx1000m -jar myprog.jar
完全に動作しました!
JVM のヒープ サイズを増やすことができるとは知りませんでした。それがまさに私の問題でした。「sw1nn」さん、すばらしいコメントをありがとうございます ;)
haskell - Haskell TVars のコンテナ
forkIO を使用してクライアントごとにスレッドを生成するゲーム サーバーがあります。たとえば、クライアントのリストとモンスターのリストをすべてのクライアントと共有したいと考えています。
私の最初のアイデアは、両方のリストを含むデータ型の 1 つの TVar コンテナーを持つことでしたが、2 つのスレッドがクライアントとモンスターを同時に変更すると、その部分が正しいことを理解していれば、そのうちの 1 つをロールバックするとします。これは不要なロールバックになります。
2 番目のアイデアは、リストを TVar にして、それらを引数として渡すことでしたが、コードをクリーンに保ち、さらにリストを追加する場合に簡単に管理できるように、リストをコンテナーに入れたいと思いました。
コンテナにいくつかの TVar を渡す方法はありますか、それとも最初のアイデアを考えすぎですか?
haskell - Haskell:2つ以上のTVarをアトミックに更新します。可能?
1つのトランザクションで2つTVar
の異なるをアトミックに更新できますか?つまりTVar
、競合を減らすために、多数のデータ構造からデータ構造を構成できますか?もしそうなら、あなたは例を提供できますか?
haskell - Haskell: TVar: 飢餓の防止
TVarを使用してWebアプリケーションに状態を保存することを検討しています(再起動時に再作成できます)。ただし、TVar の競合の側面が気になります。実行時間の短いトランザクションが頻繁に発生すると、継続的にトランザクションが中断されるため、長時間のトランザクションが不足する可能性があるようです。また、実行時間の長いトランザクションが再起動し続けると、CPU の負荷が増加し、これらのトランザクションの長さがさらに長くなる傾向があります。最終的に、これによりサーバーが完全に応答しなくなる可能性があると思います。
これを考慮して、私はこれらの質問があります:
(1) TVar (または別のデータ型) は、同時試行/再試行ではなく、ロックを使用できますか。
(2) TVar (または別のデータ型) は、いくつかの異なる競合メカニズム、つまり「トランザクションを別のトランザクションを実行する前に 1 秒間実行させる」、または少なくともトランザクションが最終的に完了することを保証する (つまり、リソース不足を防ぐ競合アルゴリズム) を持つことができますか?実行時間の長いトランザクション)。
haskell - デッドロックやリソース枯渇のない並行汎用データ構造
私は最近、 に関して多くの質問をしましたが、TVar
ライブロックについてはまだ懸念があります。
だから私はこの構造を考えました:
- 各トランザクションには一意の優先度が割り当てられます (おそらく、作成順に割り当てられます)。
- トランザクションは、アクセスするデータに対して読み取り/書き込みロックを取得しようとします。当然、同時読み取りは問題ありませんが、1 つの書き込みロックが他のすべて (読み取りと書き込みの両方) を除外します。
- トランザクション A がトランザクション B よりも優先度が高いとします。A がロックを保持している場合、B は待機しますが、B がロックを保持しており、A がそれを望んでいる場合、B はロックから起動され、A はそれを取得し、トランザクション B は ( のように
TVar
) 再起動します。ただし、B は再試行の現在の優先度を維持します。 - ロックが解放され、待機中のトランザクションがある場合、最も優先度の高いトランザクションに移動し、残りは引き続き待機します。
このシステムは、デッドロックを防ぐだけでなく、( とは異なり) 飢餓も防ぐと私は信じていTVar
ます。そのようなシステムを実装した人がいるかどうか疑問に思っていました.
もちろん、このようなアプローチは、ユーザーが優先順位を指定できるように簡単に拡張できます。
優先度は、優先度が高いペアの可能性がありますが(user_supplied_prio, auto_increment)
、user_supplied_prio
同じ優先度のタスクが FIFO 順で解決されます。
コメント/解決策:
実際、考えてみると、Haskell には、IORef
すべてのデータをラップしたものを使用し、atomicModifyIORef
. これatomicModifyIORef
により、トランザクションが順番に適用されます。ただし、これはデータ構造がシーケンシャル (事実上 1 つのスレッドに制限されている) であることを意味すると考えるかもしれませんが、実際には遅延のために並列です。
これを説明するために、高価な関数を考えてみましょうf
。Data.Map
これをキー「foo」を持つデータに適用します。
これは に置き換え(foo -> x)
られ(foo -> future(f x))
ます。(f x)
このスレッドは、実際に何が何であるかを解決し続けますが、それまでの間、「バー」に g を適用できます。g を "bar" に適用すると "foo" の結果は必要ないため、これを同時に解決できます。
デッドロックや飢餓は発生せず、最終的にはすべてのトランザクションが処理されます (おおよそ、受信した順序で)。
clojure - 参照は STM トランザクション内で本当に一貫していますか?
私はclojure.org/refsでそれを読みました
Ref のすべての読み取りでは、トランザクションの開始点 (その「読み取りポイント」) での「Ref world」の一貫したスナップショットが表示されます。トランザクションには、行った変更が表示されます。これはイントランザクション値と呼ばれます。
ウィキペディアのスナップショット分離へのリンクもあります。これは、トランザクションが開始されると、任意の数の参照の読み取りが互いに一貫していることを意味します。
テストケースを作った...
出力は次のとおりです。
not の値は、 r1 = 3
ref1の deref でが 3 つのトランザクションが発生した後に r1 の値を選択してr1 = 0
いることを示唆しています。deref-delay-deref
sleep
delay-then-inc-ref
ensure
特定のトランザクション中に他のトランザクションによる参照への更新を防ぐことについては知っていますが、ここでは当てはまらないと思います。ref1
トランザクションの開始と一致する値が表示される限り、変更されても気にしません。
この動作は、上記の参照ドキュメントにどのように適合しますか?
compiler-construction - 多言語コンパイラまたはオプティマイザの検索(c、c ++、java)
一言で言えば、私はオープンソースのコンパイラまたはオプティマイザを編集して、従来のロックの実装をソフトウェアの多国籍メモリトランザクションに変更する方法を探しています。私は3つのターゲット言語、C、C ++、およびJavaを持っています。1つのアイデアは、GCCがstmをサポートするようになったため、GCCを使用することです。問題は、GCJによってダンプされたJavaバイトコードにこれらの変更を実装する方法が考えられないことです。llvmでも同じ問題が発生します。
tldr; ソースコードまたはソースコードの中間表現を簡単に変更できるgccやllvmなどのコンパイラまたはオプティマイザを見つけようとしています。
transactions - STM の実装に関する質問
STM がどのように実装されているかについて、まったく異なる 2 つの説明を読みました。おそらく両方が有効であるか、一方が間違っている可能性があります。誰かが光を当ててくれることを願っています。
テイク 1 (ウィキペディア): すべてのスレッドが共有メモリを変更できますが、トランザクション内の読み取りと書き込みはすべてログに記録されます。トランザクションの最後に、システムは他のスレッドが同時にメモリに変更を加えていないことを確認します。変更がない場合、トランザクションはコミットされます。それ以外の場合は、トランザクションが再開されます。
- Q: これが有効な実装である場合、同じトランザクション内で 2 つのスレッドを実行できるようにするのは無意味に思えます。それらは互いの書き込みを読み取り、トランザクション ブロック内の計算は不正な形式になります。
テイク 2 (ソースが見つからない): プログラムがトランザクションに入ると、その中に含まれるすべての変数のコピーを取得し、それらを使用して街に行くことができます。トランザクションの最後に、システムはマスターをコピーで更新しようとします。コピーが最初に作成されてからマスターが変更されていない場合、トランザクションはコミットされます。それ以外の場合は、トランザクションが再開されます。
また、2 つのスレッドが同時に同じトランザクションに入るとどうなりますか? これは一種の競合状態を引き起こしませんか? どちらも同じ共有メモリを変更しようとしているため、両方を再起動する必要があり、システムが介入して 1 つのスレッドに冷却するように指示しない限り (ロックのようなもの =)、問題は無限に続きます。ここにコンセプトがありません。
concurrency - 一貫性を保つために、トランザクションで複数の Clojure ref を読み取る必要がありますか?
これは、Clojure の並行性をよりよく理解したいという私の願望によって動機付けられた理論的な質問です。
私がボイドを書いているとしましょう。各ボイドは、ワールド グリッドを表すベクトルまたは参照内の位置を変更する個別の緑色のスレッドであると仮定します。ヒッキーのアリのコロニーを考えてみてください。
現在、Clojure.org のドキュメントには、「Ref のすべての読み取りでは、トランザクションの開始点 (その「読み取りポイント」) の時点での「Ref world」の一貫したスナップショットが表示される」と記載されています。
これは、トランザクション内で (つまり、dosync コンテキスト内で) ref のベクトルを読み取ることによって、シミュレーションの一貫したスナップショットを取得することしかできないということですか?
ありがとう!