12

同期との関係を理解するのに助けが必要です。理解しようとしている例を読めば読むほど、何も理解していないと感じます。時々、これだ、わかった、と感じることがありますが、別の例を見ると、また混乱してしまいます。それを正しくするのを手伝ってください。

操作 A が操作 B と同期するのは、A が解放セマンティクスを使用したアトミック変数 m へのストアであり、B が取得セマンティクスを使用した同じ変数 m からのロードであり、B が A によって格納された値を読み取る場合です。また、次の場合、操作 A は操作 B の前に発生するとも言います。

  • A が B と同じスレッドで実行され、A がプログラム順序で B の前にある、または
  • A が B と同期する、または
  • A は他の操作 C の前に発生し、C は B の前に発生します

わかった。この例を見ると

thread0 実行 | スレッド1が実行します


x ストア (リリース) | x をロード (取得)

x here へのストアは、x からのロードと同期しますか? ここで同期との関係がある場合、x へのストアは x からのロードの前に発生するため、スレッド 0 で x へのストアの前にシーケンス処理されたものはすべて、スレッド 1 の x からのロードの前に発生します。これは、ここで強制的な順序付けがあることを意味します。そうですか?しかし、この場合、定義の「およびBがAによって格納された値を読み取る」部分が何を意味するのかわかりませんか? スレッド 1 がスレッド 0 よりも速い場合、古い値を読み取る可能性があります。では、ここでの関係はどのようなもので、何か関係があるのでしょうか? 存在しない場合、どうすればその関係を提供できますか?

前もって感謝します。

4

1 に答える 1

9

専門用語に精通しているとは言えませんが、こんな感じです。用語には .NET 定義を使用します。「他のプロセッサが後続の操作の効果の前にその効果を常に確認する場合、操作は取得セマンティクスを持ちます。操作の効果の前に他のプロセッサが先行するすべての操作の効果を確認する場合、操作はリリース セマンティクスを持ちます。それ自体。

この例では、ストアとロードの間に強制的な順序付けはありません。どちらを先に実行してもかまいません。ストア操作がたまたまロード前に実行されると、A は B と同期します。これが発生すると、ロード (取得) 後の操作が実行される前に、ストア (解放) の前のすべての操作が実行されることが保証されます。

ただし、ストアの前にロード操作が実行される場合があります。その場合、A は B と同期しません (「B が A によって格納された値を読み取る」という条件が真ではないため)。そのため、ロード後の操作は、ストアに先行する操作の前に実行される可能性があります。順番があいまいです。

リリース セマンティクスは、x の特定の値に対して、2 番目のスレッドで同じ格納された値をロードできるようになる前に (およびロードに続く操作を実行できるようになる前に)、ストアの前の操作が実行されることを認識できることを保証します。 .

count と flag がゼロに初期化され、両方のスレッドが並行して実行されると仮定しましょう:

thread0:
st          count, 1   (A)
st.release  flag, 1    (B)

thread1:
ld.acquire  flag       (C)
ld          count      (D)

A が B の前に発生し、C が D の前に発生することがわかっています。これは、それらの順序が解放と獲得のセマンティクスによって強制されるためです。B と C の順序は定義されていません。B が C と同期し、A が D の前に発生することがわかっている場合にのみ定義されます (A が B の前に C が D の前に発生するように)。

スレッド 1 では、フラグが 1 の場合、カウントは常に 1 です。フラグが 0 の場合、カウントは 0 または 1 のいずれかになります。フラグをテストして、他のスレッドが値をカウントに設定したかどうかを判断できます。

取得と解放のセマンティクスがないと、ロードとストアの順序が変更され、フラグとカウントの両方が 0 または 1 になり、相互に依存することはありません。

B が C の前に発生することを保証したい場合は、セマフォまたはその他の待機とシグナルのメカニズムを使用できます。前の例では、フラグが設定されるのをビジー待機することで、順序を強制できました。

thread1:
ld.acquire  flag       (C)
repeat C while flag == 0
ld          count      (D)
于 2011-01-14T17:07:54.850 に答える