首页 > 代码库 > 信号量的使用

信号量的使用

 1 class BasicWaitHandle 2 { 3   static EventWaitHandle _waitHandle = new AutoResetEvent (false); 4   5   static void Main() 6   { 7     new Thread (Waiter).Start(); 8     Thread.Sleep (1000);                  // Pause for a second... 9     _waitHandle.Set();                    // Wake up the Waiter.10   }11  12   static void Waiter()13   {14     Console.WriteLine ("Waiting...");15     _waitHandle.WaitOne();                // Wait for notification16     Console.WriteLine ("Notified");17   }18 }

技术分享

 

 1 class TwoWaySignaling 2 { 3   static EventWaitHandle _ready = new AutoResetEvent (false); 4   static EventWaitHandle _go = new AutoResetEvent (false); 5   static readonly object _locker = new object(); 6   static string _message; 7   8   static void Main() 9   {10     new Thread (Work).Start();11  12     _ready.WaitOne();                  // First wait until worker is ready13     lock (_locker) _message = "ooo";14     _go.Set();                         // Tell worker to go15  16     _ready.WaitOne();17     lock (_locker) _message = "ahhh";  // Give the worker another message18     _go.Set();19     _ready.WaitOne();20     lock (_locker) _message = null;    // Signal the worker to exit21     _go.Set();22   }23  24   static void Work()25   {26     while (true)27     {28       _ready.Set();                          // Indicate that we‘re ready29       _go.WaitOne();                         // Wait to be kicked off...30       lock (_locker)31       {32         if (_message == null) return;        // Gracefully exit33         Console.WriteLine (_message);34       }35     }36   }37 }

技术分享

 

生产者/消费者:

 1 using System; 2 using System.Threading; 3 using System.Collections.Generic; 4   5 class ProducerConsumerQueue : IDisposable 6 { 7   EventWaitHandle _wh = new AutoResetEvent (false); 8   Thread _worker; 9   readonly object _locker = new object();10   Queue<string> _tasks = new Queue<string>();11  12   public ProducerConsumerQueue()13   {14     _worker = new Thread (Work);15     _worker.Start();16   }17  18   public void EnqueueTask (string task)19   {20     lock (_locker) _tasks.Enqueue (task);21     _wh.Set();22   }23  24   public void Dispose()25   {26     EnqueueTask (null);     // Signal the consumer to exit.27     _worker.Join();         // Wait for the consumer‘s thread to finish.28     _wh.Close();            // Release any OS resources.29   }30  31   void Work()32   {33     while (true)34     {35       string task = null;36       lock (_locker)37         if (_tasks.Count > 0)38         {39           task = _tasks.Dequeue();40           if (task == null) return;41         }42       if (task != null)43       {44         Console.WriteLine ("Performing task: " + task);45         Thread.Sleep (1000);  // simulate work...46       }47       else48         _wh.WaitOne();         // No more tasks - wait for a signal49     }50   }51 }
 1 static void Main() 2 { 3   using (ProducerConsumerQueue q = new ProducerConsumerQueue()) 4   { 5     q.EnqueueTask ("Hello"); 6     for (int i = 0; i < 10; i++) q.EnqueueTask ("Say " + i); 7     q.EnqueueTask ("Goodbye!"); 8   } 9  10   // Exiting the using statement calls q‘s Dispose method, which11   // enqueues a null task and waits until the consumer finishes.12 }

 

信号量的使用