示例
下面的代码示例创建一个信号量,其最大计数为3,初始计数为零。 该示例启动五个线程,这会阻止等待信号量。 主线程使用 Release(Int32) 方法重载将信号量计数增加到其最大值,从而允许三个线程进入信号量。 每个线程使用 Thread.Sleep 方法等待一秒,以模拟工作,然后调用 Release() 方法重载以释放信号量。 每次释放信号灯时,都将显示以前的信号量计数。 控制台消息跟踪信号量使用。 每个线程的模拟工作时间间隔略有增加,使输出更易于读取。
C# 复制
using System;
using System.Threading;
public class Example
{
// A semaphore that simulates a limited resource pool.
//
private static Semaphore _pool;
// A padding interval to make the output more orderly.
private static int _padding;
public static void Main()
{
// Create a semaphore that can satisfy up to three
// concurrent requests. Use an initial count of zero,
// so that the entire semaphore count is initially
// owned by the main program thread.
//
_pool = new Semaphore(0, 3);
// Create and start five numbered threads.
//
for(int i = 1; i <= 5; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Worker));
// Start the thread, passing the number.
//
t.Start(i);
}
// Wait for half a second, to allow all the
// threads to start and to block on the semaphore.
//
Thread.Sleep(500);
// The main thread starts out holding the entire
// semaphore count. Calling Release(3) brings the
// semaphore count back to its maximum value, and
// allows the waiting threads to enter the semaphore,
// up to three at a time.
//
Console.WriteLine("Main thread calls Release(3).");
_pool.Release(3);
Console.WriteLine("Main thread exits.");
}
private static void Worker(object num)
{
// Each worker thread begins by requesting the
// semaphore.
Console.WriteLine("Thread {0} begins " +
"and waits for the semaphore.", num);
_pool.WaitOne();
// A padding interval to make the output more orderly.
int padding = Interlocked.Add(ref _padding, 100);
Console.WriteLine("Thread {0} enters the semaphore.", num);
// The thread's "work" consists of sleeping for
// about a second. Each thread "works" a little
// longer, just to make the output more orderly.
//
Thread.Sleep(1000 + padding);
Console.WriteLine("Thread {0} releases the semaphore.", num);
Console.WriteLine("Thread {0} previous semaphore count: {1}",
num, _pool.Release());
}
}
注解
使用 Semaphore 类控制对资源池的访问。 线程通过调用从类继承的方法进入信号量, WaitOne WaitHandle 并通过调用方法释放信号量 Release 。
每次线程进入信号量时,信号量的计数都将减少,并在线程释放信号量时递增。 如果计数为零,则后续请求会阻塞,直到其他线程释放信号量。 当所有线程都已释放信号量后,计数将达到创建信号量时指定的最大值。