問題タブ [lifo]
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.
c - アトミックな比較とスワップで実装された同時の LIFO スタックの破損を防ぐ方法
以下は、Intel CPU で GNU 組み込みの比較およびスワップを使用して実装された並行スタックで発生している問題を示す簡略化された C プログラムです。何が起こっているのかを理解するのにしばらく時間がかかりましたが、今では、アトミックな比較とスワップによって提供される保証の範囲内であることがわかります.
ノードがスタックからポップされ、変更されてからスタックに戻されると、変更された値がスタックの新しい先頭になり、破損する可能性があります。test_get のコメントは、これを引き起こすイベントの順序を説明しています。
同じノードを同じスタックで確実に複数回使用する方法はありますか? これは誇張された例ですが、変更されていないノードを gHead に返すだけでも、他のノードがリークする可能性があります。このデータ構造の元のポイントは、同じノードを繰り返し使用することでした。
8 つの論理コアでこのテストを実行しています。4 つのスレッドのみを使用する場合、問題はめったに発生しませんが、8 の場合は簡単に再現できます。Intel Core i7 を搭載した MacBook を使用しています。
これを解決したライブラリやフレームワークを使用することに興味はありません。どのように解決されたか知りたいです。ありがとうございました。
編集:
私の場合、うまくいかない2つの解決策があります。
一部のアーキテクチャは、値ではなくアドレスに対してアトミック テストを実行する ll/sc 命令ペアを提供します。同じ値であっても、アドレスへの書き込みは成功を妨げます。
一部のアーキテクチャでは、ポインター サイズより大きい比較とスワップが提供されます。これにより、モノトニックカウンターは、使用されるたびにアトミックにインクリメントされるポインターとペアになり、値が常に変化します。一部の Intel チップはこれをサポートしていますが、GNU ラッパーはありません。
これが問題のプレイバイプレイです。2 つのスレッド A と B はtest_get
、 で同じ値をresult
持ち、 ではない点に到達しNULL
ます。次に、次のシーケンスが発生します。
- スレッド A は比較とスワップを渡し、
result
から戻ります。test_get
- スレッド A は、
result
- スレッド B が逆参照
result
し、スレッド A がそこに置いたものを取得します - スレッド A は終了し
result
、呼び出しますtest_put
test_put
スレッド A は結果を元に戻す際に比較とスワップを渡しますgHead
- スレッド B は比較に到達し、スワップイン
test_get
してパスします gHead
スレッド B は、スレッド A からの値で破損しています
これは、スレッド A を変更する必要のない 3 つのスレッドを使用した同様のシナリオですresult
。
- スレッド A は比較とスワップを渡し、
result
から戻ります。test_get
- スレッド A はコンテンツを変更しません。
result
- スレッド B が逆参照
result
し、有効な値を取得しますscratch
- 無関係な値でスレッド C を呼び出し
test_put
、成功する - スレッド A が呼び出し、元に戻す
test_put
ことに成功するresult
gHead
- スレッド B は比較に到達し、スワップイン
test_get
してパスします gHead
スレッド B は、スレッド C が追加したものを漏らして破損しました
どちらのシナリオでも、問題は、スレッド B が get の比較とスワップに到達する前に、スレッド A が比較とスワップを 2 回 (get で 1 回、次に put で) 渡すことです。スレッド B が持つスクラッチの値は破棄する必要がありますが、gHead の値が正しいように見えるため、破棄する必要はありません。
実際に防止せずにこの可能性を低くする解決策は、バグの追跡を困難にするだけです。
スクラッチ変数は、アトミック命令が開始する前に結果の参照解除された値が配置される場所の単なる名前であることに注意してください。名前を削除すると、中断される可能性のある逆参照と比較の間のタイム スライスが削除されます。
アトミックとは、全体として成功または失敗することを意味することにも注意してください。問題のハードウェアでは、ポインターのアライメントされた読み取りは暗黙的にアトミックです。他のスレッドに関する限り、ポインターの半分だけが読み取られた割り込み可能ポイントはありません。
java - LIFO 順序で提供される待機リストを持つセマフォまたはロック
の実装に続くキャッシュとページのミスを最小限に抑えるために、待機スレッドの LIFO 順序付きリストを使用して効率的なセマフォまたはロックを探しますFixedThreadPoolExecutor
。
javascript - RegEx - 試合イベントの LIFO バッファ
Javascript で正規表現を使用して、試合イベントで LIFO バッファを作成するにはどうすればよいですか?
次に例を示します。
入力:
出力は次のようになります。
assembly - Intel ベースのアセンブリ Lang。スタックからの出力
したがって、現時点での出力は次のとおりです。
エリア: 17 | ポイント: 1 | 確率: 64 / 134519798
それがいつあるべきか:
エリア: 1 | ポイント: 17 | 確率: 1 / 64
スタックにプッシュされた値は、最初から最後まで続きます。
64
1
17
1
したがって、最初に 1、次に 17...1....64 にする必要があります。最初の 1 が無視されているように見えるので、何が見つかるかを調査しようとしましたが、不足しています。スタックにプッシュしている変数に値があることを確認しました。
任意の助けをいただければ幸いです。
asynchronous - LIFO ロジックで動作する MailboxProcessor
F# エージェントについて学んでいます ( MailboxProcessor
)。
私はかなり型破りな問題に取り組んでいます。
dataSource
ストリーミング データのソースである1 つのエージェント ( ) があります。データは一連のエージェント (dataProcessor
) によって処理される必要があります。dataProcessor
ある種の追跡装置と考えることができます。dataProcessor
が入力を処理できる速度よりも速くデータが流れ込む場合があります。- 多少の遅れがあってもOKです。ただし、エージェントがその作業を常に把握し、時代遅れの監視が重ならないようにする必要があります。
この問題に対処する方法を模索しています。
最初のアイデアは、スタック(LIFO)を に実装することdataSource
です。データを受信して処理できるようdataSource
になったときに、利用可能な最新の観測を送信します。このソリューションは機能する可能性がありますが、ブロックして再アクティブ化する必要があるdataProcessor
ため、複雑になる可能性があります。dataProcessor
とそのステータスを に通信するdataSource
ため、双方向通信の問題が発生します。この問題はblocking queue
、消費者と生産者の問題に要約される可能性がありますが、私にはわかりません..
2 番目のアイデアは dataProcessor
、メッセージの並べ替えを処理することです。このアーキテクチャでは、 は更新をのキューdataSource
に投稿するだけです。キューで利用可能な最新のデータをフェッチするために使用します。これが進むべき道かもしれません。ただし、現在の設計でメッセージのキューをクリアして、古い古いメッセージを削除できるかどうかはわかりません。さらに、ここでは、次のように書かれています。dataProcessor
dataProcessor
Scan
MailboxProcessor
残念ながら、現在のバージョンの F# の TryScan 関数は 2 つの点で壊れています。まず、要点はタイムアウトを指定することですが、実装は実際にはそれを尊重しません。具体的には、無関係なメッセージがタイマーをリセットします。第 2 に、他の Scan 関数と同様に、メッセージ キューはロックされた状態で検査されます。これにより、任意の長い時間になる可能性があるスキャンの間、他のスレッドがポストすることを防止できます。その結果、TryScan 関数自体が並行システムをロックアップする傾向があり、呼び出し元のコードがロック内で評価されるため、デッドロックが発生することさえあります (たとえば、関数の引数から Scan または TryScan へのポストは、ロックの下のコードが待機をブロックしているときにエージェントをデッドロックする可能性があります)。すでに下にあるロックを取得します)。
最新の観測値が跳ね返ることが問題になる場合があります。この投稿の著者である @Jon Harrop は、次のように提案しています。
私はそれを中心に設計することに成功し、結果として得られたアーキテクチャは実際にはより優れたものになりました. 本質的に、私は熱心に
Receive
すべてのメッセージを処理し、独自のローカル キューを使用してフィルタリングします。
このアイデアは確かに検討する価値がありますが、コードをいじり始める前に、ソリューションをどのように構築できるかについていくつかの意見を歓迎します。
ありがとうございました。
vhdl - LIFO メモリ vhdl コードの理解
私はこのコードを lifo メモリ用に持っていますが、27 行 (if(last = n-2) then full <= '1'; end if;) で最後の信号が n-1 と等しくない理由がわかりません。誰かが私にそれを説明できれば、私は本当に感謝しています.
java - 再挿入時に前面にプッシュする Java lifo クラス (スタック) を使用する準備はできていますか?
一意の値を持つ Java LIFO 構造を探しています。さらに、再挿入時にすでに挿入された値を前面に昇格させる必要があります。たとえば、フォーカスされたウィンドウの順序を追跡すると便利です。
Stack
orを拡張または使用して実装するのはそれほど難しいことではないことはわかっていますLinkedHashSet
が、標準 Java クラスの既存の実装を見逃している可能性があります。
c++ - 常に等しい結果になる double のスタックの比較
2 つのスタックを比較して、それらが等しいかどうかを確認しようとしています。残念ながら、このコードでは、スタックが等しくなくても、すべての比較でスタックが等しいと言われています。
Stack_implementation.cpp
スニペット:
main.cpp
関連スニペット:
出力は常に
stack1 = stack2
誰が何が悪いのか知っていますか?