un

guest
1 / ?
back to lessons

インタタングルが形成される方法

二つのサブシステムは、独立したモジュールとして生まれます。時間の経過とともに、それぞれが共有ゴッドオブジェクトにフィールドを蓄積します:グローバル構造体の構成、シングルトンマネージャー、静的クラス。各追加:孤立した場合に正しい。結合:小規模なテストでは見えない。

インタタングルパターン: システムAとBがスナップショットやインターフェースがない共有状態を共有している

この硬化された3つの基盤:

VLCメディアプレーヤー。オーディオ、ビデオ、およびプレイリストは、グローバルプレイヤー状態を保護する単一のロックを共有しています。スキップトータイムリクエストはロックを取得し、再生位置を変更し、アウディーバッファをフラッシュします。ビデオサブシステムは同じロックを待っていますが、停止します。プレイリストサブシステムも同じロックを待っており、事前読み込みできません。結果: 独立したサブシステムが単一の状態オブジェクトを通じてシリアル化されています。パフォーマンスコスト: N = サブシステムの数で割り算されたロック競合のO(N)、すべての操作遅延に比例します。

Redisイベントループ。 AOF fsync (ディスク書き込み)、レプリケーション (ネットワーク書き込み)、およびコマンド実行 (CPU) は、単一スレッドのイベントループを共有します。各: 孤立した場合に正しい。遅いfsyncはコマンド実行を停止します。レプリケーション遅延は書き込み負荷下で悪化します。結合点: 違う遅延プロファイルの操作が共有する単一の実行コンテキスト。

LevelDB VersionSet。 書き込みパス(メモテーブルフラッシュ)およびバックグラウンドコンパクションは、VersionSetロックを共有します。コンパクションジョブは10ミリ秒以上ロックを保持します。書き込みパスが停止します。両方の操作は必要です。結合: 構造的ではなくタイミング問題です。

重要な区別

インタタングルは、2つのスレッドが共有状態にアクセスし、同期がない場合にレース条件が発生します。解決策: ロックを追加します。

インタタングル: 2つのサブシステムがデザイン上で状態を共有しています。ロックを追加することで結合を修正しない;それらはアクセスをシリアル化します。サブシステムは依然として状態を共有しています。ボトルネックが引き締まります。

VLCインタタングルにロックを追加することは悪くなります: それから今後オーディオ、ビデオ、およびプレイリストはすべて単一のロックを待機します。構造的な修正: 各サブシステムに独自の状態を提供します。フェーズスナップショット: 相互作用境界で共有状態のスナップショットを凍結し、それぞれのサブシステムが独立してスナップショットを読み取らせ、最後に書き戻します。

構造的vsタイミング

インタータングルールの鍵となる診断質問: ミューテックスを追加することで問題が解決されるか、それともそれが悪くなるか?

レースコンディション: ミューテックスを追加することで解決される。正しいアクセス順序で腐敗を排除する。

インタータングルール: ミューテックスを追加することでアクセスがシリアル化されるが、構造的結合が保持される。サブシステムは依然として共有状態を共有している。負荷が高まる際に、それぞれが互いにブロックされる。ボトルネックが狭まる。

二つのサブシステムがどうやってインタタングルになるかを説明してください。このことが単なるレース条件ではなく構造的である理由は何ですか?

インタータングルールを見つける方法

3つの検出信号があります。

1. サブシステム間で共有するmutableフィールド。神のようなオブジェクトがあり、複数のサブシステムによって読み書きされる。1つのサブシステムのフィールドアクセスを削除することで別のサブシステムが破壊される場合、それらは状態を共有している。

2. 関連していない操作を同じロックで保護している。オーディオのフラッシュとビデオのデコードとプレイリストの取得を同じロックで保護する3つのサブシステム、異なるレイテンシープロファイルを持つ。同じロック名の操作が同じロックで保護されているというにおい。

3. 負荷が増すとパフォーマンスが悪くなる。操作Aのレイテンシーは、操作Bと同時に実行される場合に悪くなる、操作AとBは独立しているように見えるが、実際には状態を共有している。

フェーズ・スナップショット・フィックス

フェーズ・スナップショット・パターン:

# BEFORE: サブシステムは共有状態に直接読み書きする
class GameWorld:
    position = {}  # shared mutable
    velocity = {}  # shared mutable

def physics_tick(world):
    for entity in world.entities:
        world.position[entity] += world.velocity[entity]  # writes shared state mid-loop
# AFTER: snapshot frozen before phase; writes go to next_state buffer
def physics_tick(world):
    snapshot = world.freeze()  # immutable view
    next_state = {}
    for entity in snapshot.entities:
        next_state[entity] = snapshot.position[entity] + snapshot.velocity[entity]
    world.merge(next_state)  # atomic merge at phase boundary

すべてのサブシステムはスナップショットを読みます。スナップショットに書き込むサブシステムはありません。書き込みはフェーズ境界で原子的にマージされるバッファに蓄積されます。サブシステムは独立して実行されます:ロック競合なし、順序依存性なし、隠れた結合なし。

解決策を適用する

チームは欠陥を報告しました:彼らのゲームエンジンのアニメーションシステムと衝突システムは共有のエンティティ変換オブジェクトに書き込むことができます。両方が同じタックで実行される場合、衝突の結果はアニメーションが最初に実行されたかによって依存します。ロックを追加することで順序が修正されたが、今度はアニメーションが衝突が広範なフェーズスイープを実行するたびに停止します。

欠陥クラスを名付けましょう。ロックを追加することが解決策ではなかった理由を説明してください。構造的な解決策を説明してください。