1

私はeverything2.comから次のような競合状態の定義を採用しています。

競合状態とは、複数の同時プロセスを実行すると(これらの目的のために、スレッドもプロセスとしてモデル化され、別々のマシンで実行されるプロセスと同様に)、の(指定されていない、通常は指定されていない)詳細に応じて異なる結果が得られる状況です。操作の順序。

次に、第3章の次のサンプルを検討します。競合状態と相互排除:

ただし、最も危険な競合状態には、共有データ構造へのアクセスが含まれます。2つのスレッドが同じデータ構造を同時に更新している場合、変更は一方のスレッドによって部分的に行われ、もう一方のスレッドによって部分的に行われる可能性があります。データ構造の内容が文字化けする可能性があります。これにより、後でデータ構造にアクセスするスレッドが混乱し、クラッシュが発生します。

明らかに、このサンプルには有害な競合状態が含まれています。

この有害な競合状態を回避するための解決策があります。

秘訣は、スレッドが一度に1つずつデータ構造にアクセスするように強制することです。これは、相互排除と呼ばれ、各スレッドが更新を完了して、次のスレッドのために構造を一貫した状態のままにしておくことができます。

上記の定義によれば、上記のソリューションにはまだ競合状態があります。

スレッドAが最初に変更を加えた場合、共有データ構造の最終的なコンテンツはスレッドBによって埋められます。スレッドBが最初に変更を加えた場合、共有データ構造の最終的なコンテンツはスレッドAによって埋められます。

しかし、今では無害な競合状態です。

このサンプルから、次の結論が得られます。

競合状態は、回避できる場合にのみ有害です。

上記の結論の両方の方向または一方の方向だけが正しいか間違っているかはわかりません。それで、この結論を反証するサンプルはありますか?

4

3 に答える 3

2

あなたが正しいです。

競合状態-複数のスレッドが同じリソースにアクセスするときに発生します。
競合状態につながるコードセクションは、クリティカルセクションと呼ばれます。競合状態を回避しようとすると、デッドロックが発生することに注意してください。

スレッドセーフなコードを作成することで、競合状態を回避できます。

  • ローカル変数。

    ローカル変数は、各スレッドの独自のスタックに格納されます。つまり、ローカル変数がスレッド間で共有されることはありません。

  • ローカルオブジェクト参照。

    すべてのオブジェクトは共有ヒープに格納されますが、ローカルで作成されたオブジェクトが作成されたメソッドをエスケープしない場合は、スレッドセーフです。

  • メンバーフィールドを揮発性、最終的、プライベートにします。

ただし、変数を共有し、それでも同期してアクセスを制御したい場合。あなたは次の方法でそれを行うことができます、

  • 明示的なロック(および条件変数)の使用
  • 同期された(暗黙のロック)の使用

これは、どのスレッドが最初にアクセスし、次にどのスレッドがアクセスするかを保証するものではありません。スレッドの使用信号をこのように制御するには。

それはさまざまな方法で達成することができます。

  • 共有オブジェクトを介したシグナリング
  • ビジーウェイト
  • wait()、notify()、notifyAll()
  • 失われた信号
  • スプリアスウェイクアップ
于 2012-08-30T06:53:28.883 に答える
1

ここで非常に重要な点を見逃しています。データ構造に対する操作は、たとえば非常に基本的な手順を追加するために、数サイクルで行われます。

ステップ1.変数の現在の値の取得ステップ2.変数の値に目的の数値を追加しますステップ3.変数の値を保存します

レジスタレベルでは、より多くのステップ数を確認できます。ただし、重要なのは、変数/データ構造のアクセスをロックすることで競合状態を回避するということは、そのデータ構造に対して1つのスレッドだけが読み取り/書き込みを行えることを意味します。他のスレッドはデータ構造の読み取りを許可されず、最初のスレッドがすべてのサイクルを完了すると、他のスレッドが変更を実行できるようになります。

スレッドが最初に行うことは、データ構造が誰にもロックされていない場合にロックを取得することです。次に、読み取り/書き込みを行います。

したがって、ロックを適切に実装すれば、競合状態は発生しないはずです。

競合状態は、2つ以上のスレッドが同じデータ構造に変更を加える可能性がある場合に存在し、ロックまたはその他のメカニズムによって回避されない場合は有害である可能性があります。

于 2012-08-30T04:22:26.293 に答える
0

同意しません。変更は、回避可能かどうかにかかわらず、望まない場合は「有害」です。

明らかに、2つのプロセスが並行して実行される場合、そのデータを変更するために常にレースが行われているため、状態の最終結果もそのレースに依存する可能性があります。

しかし、競合状態について話すとき、そのデータの一貫性が競合プロセスによって破られる可能性がある場合、有害な競合状態が発生します。

于 2012-08-30T08:19:54.433 に答える