3

lock ステートメントを使用していないと仮定すると、これは悪い習慣ですか?

public static class Foo
{
  public static string Bar()
  {
    bool working;

    while (working)
    {
      // Loop until ready to run.
    }

    working = true;

    // Do stuff here.

    working = false;
    return "done."
  }
}

編集 -

このようなことを試みた後、いくつかの理由でそれが実現不可能であることに気付きました。私はただ興味がありました..私が投稿した例は機能しません。

4

6 に答える 6

4

ループは CPU を消費するプロセスです。

つまり、あなたがすることすべてがただ待っているということです。それは良いことではありません。

于 2009-03-13T18:58:59.617 に答える
4

まず、作業はメソッドに対してプライベートであるため、効果はありません。これを呼び出す 2 つのスレッドは、それぞれ独自の「作業」を行います。効果を得るには、静的フィールドにする必要があります。

それでも、競合状態が発生する可能性があります。2 つのスレッドが同時にこれにヒットし、while(working) 条件を通過してから、working = true; を設定できます。同時に物事を行っている。

ロックまたはセマフォを使用すると、これを解決するのに役立ちます。

于 2009-03-13T18:59:29.693 に答える
2

別のスレッドから変更されることを意味すると仮定するとworking、2 つの問題があります。

  1. volatile staticあなたはメンバーに働くべきです。Volatile は、最適化で「賢い」ことを何も試みないようにコンパイラーに指示します。

  2. 「スピンロック」と呼ばれるものを書きました。それが最善のアプローチである特別な状況があります。workingしかし、変数が設定されるまでスレッドが CPU を消費するため、通常はひどい考えです。

于 2009-03-13T18:59:34.310 に答える
1

はい、これは悪い習慣です。

lock ステートメントを使用しないのはなぜですか? Monitorクラスを見てください。相互排除と同期を提供できます。

回転ループと非スレッドセーフ変数の動作は使用しないでください。

于 2009-03-13T19:00:15.073 に答える
1

作業が複数のスレッドに表示される場合 (別のポスターが述べたように、それはローカル変数です)、現在書かれているように、システム内の他のコアが正しい順序で作業するための更新を確認するという保証がないという別の問題があります。System.Threading.Thread.MemoryBarrier などのメモリ バリアは、作業中への書き込みが "Do stuff here" を過ぎて CPU によって再順序付けされないことを保証するために必要です。

ただし、代わりにロックの使用を検討する必要があります。ロックフリー プログラミングを正しく行うのは非常に困難です。

于 2009-03-13T19:04:39.463 に答える
0

ロックを使用することは、並行性の問題を防ぐ唯一の方法です (ロックを使用しない以外は)。

public static class Foo
{
  private static object barLock = new object();

  public static string Bar()
  {
    lock (barLock)
    {
      // Do work
      return "Done";
    }
  }
}
于 2009-03-13T19:44:43.873 に答える