1

私は質問を理解しようとしています(そして、それぞれに対する答え):

以下のコードを添付して

コード内のコメントは次のことを示しています。

// set the event - I thought this would mean both waiting threads are allowed to continue
// BUT thread2 runs and thread1 stays blocked indefinitely

しかし、スレッドのいずれかが無期限にブロックされる方法と理由がわかりません...
コードを実行しようとしましたが、無期限のブロックを監視しませんでした...

この質問(およびそれぞれの回答)で何が欠けていますか?

private static void Test()
{
    // two threads - waiting for the same autoreset event
    // start it unset i.e. closed i.e. anything calling WaitOne() will block
    AutoResetEvent autoEvent = new AutoResetEvent(false);

    Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
    thread1.Start();  // this will now block until we set the event

    Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
    thread2.Start();  // this will now also block until we set the event

    // simulate some other stuff
    Console.WriteLine("Doing stuff...");
    Thread.Sleep(5000);
    Console.WriteLine("Stuff done.");

    // set the event - I thought this would mean both waiting threads are allowed to continue
    // BUT thread2 runs and thread1 stays blocked indefinitely
    // So I guess I was wrong and that Set only releases one thread in WaitOne()?
    // And why thread2 first?
    autoEvent1.Set();
}

更新:
このコードを次のように起動していました:

using System;
using System.Threading;

namespace bothCallWaitOne
{
  class Program
  {
    static void Main(string[] args)
    {

      // two threads - waiting for the same autoreset event
      // start it unset i.e. closed i.e. anything calling WaitOne() will block
      AutoResetEvent autoEvent = new AutoResetEvent(false);

      WriteSomeMessageToTheConsole();
      Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
      thread1.Name = "1111111111";
      thread1.Start();  // this will now block until we set the event

      //Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
      Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
      thread2.Name = "222222222222";
      thread2.Start();  // this will now also block until we set the event

      // simulate some other stuff
      Console.WriteLine("Doing stuff...");
      Thread.Sleep(5000);
      Console.WriteLine("Stuff done.");

      // set the event - I thought this would mean both waiting threads are allowed to continue
      // BUT thread2 runs and thread1 stays blocked indefinitely
      // So I guess I was wrong and that Set only releases one thread in WaitOne()?
      // And why thread2 first?
      autoEvent.Set();
      Console.ReadLine();
    }

    static void WriteSomeMessageToTheConsole()
    {
      Console.WriteLine(Thread.CurrentThread.Name);
    }
    static void WriteSomeOtherMessageToTheConsole()
    {
      Console.WriteLine(Thread.CurrentThread.Name);
    }

  }
}

また、無期限のブロックは見られません。

コードを実行した結果の出力は次のとおりです。

Doing stuff...
222222222222
1111111111
Stuff done.

(スレッドが無期限にブロックされるという) 議論されたトピックを再現するために、コードを実行 (更新、変更、インクリメント) するにはどうすればよいですか?

4

3 に答える 3

1

MSDNから

  • AutoResetEvent は、待機中のスレッドが1 つ解放されるまでシグナル状態のままです。

AutoResetEvent は改札口として機能します。を 1 回呼び出すと、スレッドは 1 つだけSet解放されます。

于 2013-03-09T08:18:45.223 に答える
0

これが問題を再現するための最終的なコードです。

他の方法で表示するためにローカルにすることautoEventはできません。静的メソッドMain()およびTest()メソッドから使​​用し、その後静的メソッドから「使用」する には、静的である必要があります。

using System;
using System.Threading;

namespace bothCallWaitOne
{
  class Program
  {
    static AutoResetEvent autoEvent = new AutoResetEvent(false);
    static void Main(string[] args)
    {
      Test();
      Console.ReadLine();
    }
    private static void Test()
    {
      // two threads - waiting for the same autoreset event
      // start it unset i.e. closed i.e. anything calling WaitOne() will block
      //AutoResetEvent autoEvent = new AutoResetEvent(false);

      //WriteSomeMessageToTheConsole();
      Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
      thread1.Name = "1111111111";
      thread1.Start();  // this will now block until we set the event

      //Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
      Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
      thread2.Name = "222222222222";
      thread2.Start();  // this will now also block until we set the event

      // simulate some other stuff
      Console.WriteLine("Doing stuff...");
      Thread.Sleep(5000);
      Console.WriteLine("Stuff done.");

      // set the event - I thought this would mean both waiting threads are allowed to continue
      // BUT thread2 runs and thread1 stays blocked indefinitely
      // So I guess I was wrong and that Set only releases one thread in WaitOne()?
      // And why thread2 first?
      autoEvent.Set();
    }
    static void WriteSomeMessageToTheConsole()
    {
      autoEvent.WaitOne();//Cannot relve symbol autoEvent
      while(true)
        Console.WriteLine(Thread.CurrentThread.Name+"****");
    }
    static void WriteSomeOtherMessageToTheConsole()
    {
      autoEvent.WaitOne();//Cannot relve symbol autoEvent
      while(true)
      Console.WriteLine(Thread.CurrentThread.Name);
    }
  }
}
于 2013-03-09T09:31:34.520 に答える
0

The ARE is a strange beast. If you read the MSDN entry for it, you will find that, if signaled once while more than one thread is waiting, it will release only one waiting thread. If, however, no threads are waiting when it's signaled, it does not keep a count of the signal and it is 'lost'.

It's a strange crossbreed between a manual reset event and a semaphore. TBH, I find it less useful than either :)

于 2013-03-09T08:21:39.040 に答える