問題タブ [livelock]
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.
concurrency - ライブロックの良い例?
私はライブロックが何であるかを理解していますが、誰かがコードベースの良い例を持っているかどうか疑問に思っていましたか? また、コードベースとは、「2 人が廊下でお互いを乗り越えようとしている」という意味ではありません。もう一度読んだら、昼食を失います。
deadlock - C# の "ロック" 構造は Interlocked.CompareExchange によって廃止されましたか??
概要:
それは私には思われる:
- 論理状態を表すフィールドを単一の不変の消費可能なオブジェクトにラップする
- への呼び出しでオブジェクトの正式な参照を更新する
Interlocked.CompareExchange<T>
- 更新の失敗を適切に処理する
は、「ロック」構造を不必要にするだけでなく、並行性に関する特定の現実をかわし、結果として多くの新しい問題を引き起こす真に誤解を招くような構造にする一種の並行性を提供します。
問題のディスカッション:
まず、ロックを使用する際の主な問題を考えてみましょう。
- ロックはパフォーマンス ヒットを引き起こすため、読み取りと書き込みには同時に使用する必要があります。
- ロックはスレッドの実行をブロックし、並行性を妨げ、デッドロックのリスクを高めます。
「ロック」に触発されたばかげた動作を考えてみましょう。リソースの論理セットを同時に更新する必要が生じた場合、リソースのセットを「ロック」します。これは、関連付けが緩い専用のロック オブジェクトを介して行います。これは、そうでなければ何の役にも立ちません (赤旗 #1)。
次に、「ロック」パターンを使用して、一連のデータ フィールドで論理的に一貫した状態変更が発生するコードの領域をマークオフしますが、フィールドを同じオブジェクト内の無関係なフィールドと混合することで自分自身を撃ちます。それらをすべて可変のままにし、これらのさまざまなフィールドを読み取るときにロックを使用する必要があるコーナー (赤旗 #2) に追い込むことで、一貫性のない状態でそれらをキャッチしないようにします。
明らかに、その設計には深刻な問題があります。ロックオブジェクトの慎重な管理 (ロック順序、ネストされたロック、スレッド間の調整、何かをするのを待っている別のスレッドによって使用中のリソースのブロック/待機など) が必要なため、やや不安定です。コンテキスト。また、デッドロックを回避するのは「難しい」と言う人もいますが、実際には非常に簡単です。あなたのためにレースを走るように頼む予定の人の靴を盗まないでください!
解決:
「ロック」の使用を完全に停止します。 一貫性のある状態またはスキーマを表す、破損しない/不変のオブジェクトにフィールドを適切にロールバックします。おそらく、表示名と内部識別子を相互に変換するための辞書のペアであるか、値と次のオブジェクトへのリンクを含むキューのヘッド ノードである可能性があります。それが何であれ、それを独自のオブジェクトにラップし、一貫性のために封印します。
書き込みまたは更新の失敗を可能性として認識し、それが発生したときにそれを検出し、無期限にブロックするのではなく、すぐに (または後で) 再試行するか、別のことを行うかを状況に応じて決定します。
ブロッキングは、実行する必要があると思われるタスクをキューに入れるための簡単な方法のように思えますが、すべてのスレッドが専用でセルフサービス型であるため、システム全体を危険にさらすリスクを冒してそのようなことを行う余裕があるわけではありません。「ロック」を使用して物事をシリアル化するのが面倒であるだけでなく、書き込みが失敗してはならないふりをしようとすることの副作用として、スレッドをブロック/フリーズするため、スレッドが応答しなくなり、役に立たなくなり、他のすべての責任が放棄されます。自分の責任を果たすために他人を助けることが必要な場合があるという事実を知らずに、自分が以前にやろうとしていたことを達成するのを頑固に待ちます。
独立した自発的なアクションが同時に発生している場合、競合状態は正常ですが、制御されていないイーサネットの衝突とは異なり、プログラマーとして、「システム」(つまり、決定論的なデジタル ハードウェア) とその入力を完全に制御できます。 0 か 1 か?) と出力、およびシステムの状態を格納するメモリであるため、ライブロックは問題にならないはずです。さらに、多数のプロセッサが同時に動作している可能性があるという事実を解決するメモリ バリアを使用したアトミック操作があります。
要約する:
- 現在の状態オブジェクトを取得し、そのデータを消費して、新しい状態を構築します。
- 他のアクティブなスレッドがまったく同じことを行っており、あなたを打ち負かす可能性があることを認識してください。ただし、すべてが「現在の」状態を表す信頼できる参照ポイントを観察します。
- Interlocked.CompareExchange を使用して、作業の基になった状態オブジェクトがまだ最新の状態であるかどうかを同時に確認し、それを新しい状態に置き換えます。それ以外の場合は失敗し (別のスレッドが最初に終了したため)、適切な修正アクションを実行します。
最も重要な部分は、失敗をどのように処理し、馬に戻るかです。これは、私たちがライブロックを避ける場所であり、考えすぎたり、十分なことをしたり、正しいことをしたりしません。ロックは、スタンピードに乗っていても馬から落ちることは決してないという幻想を作り出し、スレッドがそのようなファンタジーの土地で空想にふけっている間、システムの残りの部分はバラバラになり、クラッシュして燃えることができます.
では、CompareExchange と不変の論理状態オブジェクトを使用したロックフリーの実装では、「ロック」コンストラクトが実行できること (より安定した方法で) を達成できないことはありますか?
これはすべて、ロックを集中的に処理した後、私が自分で実現したことですが、別のスレッドで検索した後、ロックフリーのマルチスレッドプログラミングは何かを簡単にしますか? 、何百ものプロセッサを備えた高度に並列なシステムに直面するとき、高度に競合するロックを使用する余裕がない場合、ロックフリープログラミングが非常に重要になるだろうと誰かが述べています。
django - Django/Postgresqlでのlivelockのデバッグ
Apache2、mod_python、およびpostgresql_psycopg2データベースバックエンドを備えたPostgreSQL8.3を使用してDjangoで適度に人気のあるWebアプリを実行します。私は時折ライブロックを経験しています。これは、apache2プロセスが数分以上CPUの99%を継続的に消費している場合に識別できます。
apache2プロセスでstrace- ppidを実行したところ、次のシステムコールが継続的に繰り返されていることがわかりました。
この正確なフラグメントはトレース内で継続的に繰り返され、最終的にapache2プロセスを強制終了する前に10分以上実行されていました。(注:これを編集して、以前のstraceフラグメントを、切り捨てられるのではなく、文字列の内容全体を表示する新しいフラグメントに置き換えました。)
上記の私の解釈は、djangoが私のテーブルaccount_profileで存在チェックを行おうとしているということですが、ある初期の時点(トレースを開始する前)で何かがうまくいきませんでした(SQL解析エラー?参照整合性または一意性制約違反?誰が知っていますか? )、そして今Postgresqlはエラー「現在のトランザクションは中止されました」を返しています。何らかの理由で、例外を発生させてあきらめる代わりに、再試行を続けます。
1つの可能性は、これがProfile.objects.get_or_createの呼び出しでトリガーされていることです。これは、account_profileテーブルにマップするモデルクラスです。おそらく、get_or_createに、広すぎる例外のセットをキャッチして再試行するように設計されたものがありますか?Webサーバーのログから、このライブロックは、サイトの登録フォームのPOSTボタンをダブルクリックした結果として発生した可能性があるようです。
この状態は、ライブサイトで過去数日間に数回発生し、介入するまで大幅に遅くなるため、無限のデッドロック以外のほとんどの問題が改善されます。:)
nhibernate - リクエストごとにセッションを使用するときにNHibernateにデッドロックされたトランザクションを再試行させるにはどうすればよいですか?
Session-Per-Requestパターンを使用している場合、トランザクション失敗の再試行をサポートする必要があるNHibernateを使用する3層アプリケーションでどのパターン/アーキテクチャを使用しますか?(これがデッドロック、タイムアウト、またはライブロックの例外であっても、ISessionは例外の後に無効になるため)。
multithreading - デッドロックとライブロックの違いは何ですか?
誰かが(コードの)例でデッドロックとライブロックの違いを説明できますか?
linux - Xenomai リアルタイムスレッドから gettimeofday() を呼び出す安全な方法はありますか?
ptpd に従って現在の時刻を確認するために、時々 gettimeofday() を呼び出す必要がある Xenomai リアルタイム スレッドを実行しています。
ただし、これを行うのは安全ではないようです。特に、Xenomai スレッドと Linux カーネルが「ライブロック」状態になることがあり、ここで説明されているように、gettimeofday() が CPU を回転させて戻らなくなります。
私の質問は、Xenomai リアルタイム スレッドから gettimeofday() の情報を安全に取得する方法はありますか? 独自のバージョンの gettimeofday() を Linux カーネルに追加することを検討しています (私のバージョンは、read_seqretry() が true を返すと失敗します。これが発生すると永久にループする通常のバージョンとは異なります)。ただし、より良い方法があれば、Linux カーネルのカスタマイズをすぐに開始したくありません。
sql-server - ライブロックとは正確には何ですか?SQLでは、いつ/どのように発生しますか? T-SQL 開発者がそれを回避するためにできることはありますか?
SQL Server のこの専門用語に遭遇しましたが、SQL Server で何が起こっているのか正確には理解できません。それが発生するSQL Serverの例を見ています...
私はグーグルで検索してきましたが、廊下の例では2人しか得られません。
c - sem_trywait() を使用するとデッドロックが発生する可能性があります
sem_trywait()
を使用すると、デッドロックまたはライブロックに陥ることができますか?
java - Java:HashMap から読み取るとその状態を変更できますか?
同期されていないものへの同時更新HashMap
は、明らかにライブロックやその他のデータ破損を引き起こす可能性があります。これを回避するには、並行バージョンを使用するか、同期メカニズムを実装する必要があります。
HashMap.get()への同時呼び出しは、再ハッシュのように HashMap の状態を変更できますか?
アップデート:
一部のコメンターは、データ構造の動作をつまらないものにするという理論的な喜びに加えて、質問の実際的な側面について疑問に思いました。
get()
の状態を変更しない場合HashMap
(および別の理由でライブロックを発生させることができない場合)、1 つのスレッドが事前に HashMap を作成し、多数のスレッドが HashMap から同時に読み取ることができます。同時読み取りが安全でない場合はConcurrentHashMap
、タイプに関係なく、すべてのマルチスレッド アクセスが必要です。