問題タブ [interlocked-increment]
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# - C# マルチスレッドの符号なしインクリメント
複数のスレッドから符号なし整数をインクリメントしたい。
Interlocked.Increment については知っていますが、符号なし整数を処理しません。lock() を使用することもできますが、パフォーマンス上の理由から、できれば使用したくありません。
通常の方法でインクリメントするだけでスレッドセーフですか?統計にのみ使用されるため、時折のインクリメントが失われても問題ありません。私が望んでいないのは、値が破損することです。
c++ - 連動操作を使用して複数の値を更新し、クリティカル セクション/ミューテックスのロックを回避できますか?
一連の値をインクリメント/変更する必要があるマルチスレッド アプリケーション (C++) があります。一連のインターロック操作を使用する場合、それらは単一のアトミック操作と見なされますか? この例のように:
それとも、同期を実行するためにロックした方がよいでしょうか? このような:
ロックが必要だと思いますが、よくわかりません...すべての値が古い状態または新しい状態にあることが非常に重要です。
.net - Interlocked.Incrementのパフォーマンス
さまざまなプラットフォームのintやlongInterlocked.Increment(ref x)
よりも速いですか遅いですか?x++
multiprocessing - InterlockedIncrement と ++
InterlockedIncrement はどのように機能しますか?
問題はマルチプロセッサ システムだけですか?
すべてのプロセッサで割り込みを無効にするのは何ですか?
c# - C# ブロック FIFO キューがメッセージをリークすることはありますか?
私は学術的なオープン ソース プロジェクトに取り組んでおり、C# で高速ブロッキング FIFO キューを作成する必要があります。私の最初の実装では、単純に同期キュー (動的拡張を使用) をリーダーのセマフォ内にラップしました。
これは、教科書にある静的配列を使用した古典的な FIFO キューの実装です。ポインターをアトミックにインクリメントするように設計されており、到達したときにポインターをゼロに戻すことはできないため (容量-1)、モジュロを別々に計算します。理論的には、Interlocked を使用することは、インクリメントを行う前にロックすることと同じです。セマフォがあるため、複数のプロデューサー/コンシューマーがキューに入る可能性がありますが、キュー ポインターを変更できるのは一度に 1 つだけです。まず、Interlocked.Increment は最初にインクリメントしてから戻るため、ポスト インクリメント値を使用して、配列内の位置 1 からストア項目を開始することに制限されていることを既に理解しています。問題ありません、一定の値になったら0に戻ります
それの何が問題なのですか?高負荷で実行していると、キューが NULL 値を返すことがあることは信じられないでしょう。繰り返しますが、キューにnullをエンキューするメソッドはないと確信しています。念のために Enqueue に null チェックを入れてみましたが、エラーは発生しませんでした。そのためのテストケースをVisual Studioで作成しました(ちなみに私はまぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁんのようにデュアルコアCPU使ってます)
コンシューマ スレッドが null を取得すると、エラーがカウントされます。1 つのプロデューサーと 1 つのコンシューマーでテストを実行すると、成功します。2 つのプロデューサと 2 つのコンシューマ、またはそれ以上でテストを実行すると、2000 のリークが検出されるという惨事が発生します。Enqueue メソッドに問題がある可能性があることがわかりました。設計上の契約により、プロデューサーは空 ( null )のセルにのみ書き込むことができますが、コードをいくつかの診断で変更すると、プロデューサーが空でないセルに書き込みを試みていることがわかりました。 " データ。
「ひどい」例外が頻繁に発生します。しかし、インクリメントはアトミックであり、ライターのセマフォは空き配列セルと同じ数のライターしか許可しないため、同時書き込みから競合が発生するのは奇妙です。
誰かがそれを手伝ってくれますか?あなたのスキルと経験を私と共有していただければ幸いです。
ありがとうございました。
c# - 最初に入力されたスレッドは、同じメソッドの終了を他の並行スレッドにどのように通知できますか?
最初に入力されたスレッドは、どのようにして他の並行スレッドに同じメソッドの終わりを知らせることができますか?
PollDPRAM() という名前のメソッドがあります。ネットワークを介して低速のハードウェアに移動し、オブジェクトのプライベート データを更新する必要があります。同じメソッドが他のスレッドによって同時に呼び出された場合、それらはトリップを実行する必要はありませんが、データが新鮮であるため、最初に来るスレッドがジョブを完了するのを待ってから終了する必要があります (たとえば、10 ~ 30 ミリ秒前でも違いはありません)。 . 2番目、3番目などのスレッドが最初に入力されていない方法で検出するのは簡単です. インターロック カウンターを使用して同時実行性を検出します。
問題: 最初のスレッドの終了を検出するために、カウンター (Interlocked.Read) を監視して、n>1 スレッドの開始時に検出された値よりも小さい値にカウンターが減少したことを検出するという不適切な選択をしました。最初のスレッドは、メソッドが終了した直後にメソッドに再び入る可能性があるため、この選択は不適切です。したがって、n>1 スレッドはカウンターのディップを検出しません。
質問: 最初に入力されたスレッドがメソッドを終了したことを正しく検出するには、この最初のスレッドがすぐに再度入力できる場合でも?
ありがとうございました
PSコードの一部
.net - Interlocked.Incrementがアトミックである場合、なぜ代わりに++を使用する必要があるのですか?
この不可分操作は。よりも高速だと思います++
。私は有利な利点だけを見Interlocked.Increment
ます。その欠点は何ですか?
c++ - 連動変数アクセスとクリティカル セクション連動インクリメントの違い
インターロックされた変数アクセスとクリティカルセクションのインターロックされたインクリメントの違いをc ++で説明できる人はいますか? よろしくお願いします。
multithreading - 「安全でない」スレッド関数を使用しても安全ですか?
少しユーモラスなタイトルで申し訳ありません。その中で「安全」という言葉の 2 つの異なる定義を使用しています (明らかに)。
私はスレッド化にかなり慣れていません (まあ、私はスレッド化を何年も使用してきましたが、非常に単純な形式しか使用していません)。現在、いくつかのアルゴリズムの並列実装を作成するという課題に直面しており、スレッドは同じデータで動作する必要があります。次の初心者の間違いを考えてみましょう。
初心者は、上記のコードでメッセージが表示されることを期待するかもしれません20000000
。確かに、最初value
は に等しく0
、次にそれをinc
掛け20000000
ます。ただし、inc
プロシージャは「アトミック」ではないため、2 つのスレッドが競合し (読み取り、インクリメント、保存の 3 つのことを行うと思いinc
ます)、多くのinc
s が事実上「失われます」。上記のコードから得られる典型的な値は10030423
.
最も簡単な回避策は、InterlockedIncrement
代わりに ofを使用することですInc
(このばかげた例でははるかに遅くなりますが、それは重要ではありません)。もう 1 つの回避策はinc
、クリティカル セクション内に配置することです (はい、このばかげた例でも非常に遅くなります)。
現在、ほとんどの実際のアルゴリズムでは、競合はそれほど一般的ではありません。実際、それらは非常に珍しいかもしれません。私のアルゴリズムの 1 つはDLA フラクタルを作成し、変数の 1 つはinc
吸着粒子の数です。ここでの競合は非常にまれであり、さらに重要なことに、変数の合計が 20000000、20000008、20000319、または 19999496 になるかどうかは気にしません。したがって、コードを肥大化させるだけなので、クリティカル セクションを使用しないInterlockedIncrement
ように誘惑されます。そして、(わずかに)遅くなり、(私が見る限り)メリットがありません。
しかし、私の質問は次のとおりです。インクリメント変数のわずかに「間違った」値よりも、競合のより深刻な結果が生じる可能性がありますか? たとえば、プログラムがクラッシュする可能性はありますか?
確かに、この質問はばかげているように思えるかもしれません。結局のところ、InterlockedIncrement
代わりに使用するコストinc
はかなり低いため (多くの場合、すべてではありません!)、安全にプレイしないのは (おそらく) ばかげているからです。しかし、これが実際に理論レベルでどのように機能するかを知ることは良いことだとも感じているので、この質問は依然として非常に興味深いと思います.
c# - Interlocked.Increment と Lock の使用について混乱している
Interlocked.Increment
と の機能を理解していますlock()
。しかし、どちらをいつ使用するかについて混乱しています。コードの領域をロックすることを意図しているのに対し、私が知る限り、Interlocked.Increment
共有されたint / long値をインクリメントします。lock()
たとえば、文字列値を更新したい場合は次のようにできますlock()
:
Interlocked
ただし、これはクラスでは不可能です。
- を介してこれを行うことができないのはなぜ
Interlocked
ですか? - これらの同期メカニズムの違いは何ですか?