C# semaphore

Semaphore 类

注意:此类在 .NET Framework 2.0 版中是新增的。

限制可同时访问某一资源或资源池的线程数。

命名空间:System.Threading
程序集:System(在 system.dll 中)

语法
 
注意

应用于此类的 HostProtectionAttribute 属性 (Attribute) 具有下面的 Resources 属性 (Property) 值:Synchronization | ExternalThreadingHostProtectionAttribute 不影响桌面应用程序(桌面应用程序一般通过双击图标,键入命令或在浏览器中输入 URL 启动)。有关更多信息,请参见 HostProtectionAttribute 类或 SQL Server 编程和宿主保护属性

使用 Semaphore 类可控制对资源池的访问。线程通过调用 WaitOne 方法(从 WaitHandle 类继承)进入信号量,并通过调用 Release 方法释放信号量。

信号量的计数在每次线程进入信号量时减小,在线程释放信号量时增加。当计数为零时,后面的请求将被阻塞,直到有其他线程释放信号量。当所有的线程都已释放信号量时,计数达到创建信号量时所指定的最大值。

被阻止的线程并不一定按特定的顺序(如 FIFO 或 LIFO)进入信号量。

线程可通过重复调用 WaitOne 方法多次进入信号量。为释放这些入口中的部分或全部,线程可多次调用无参数的 Release 方法重载,也可以调用 Release(Int32) 方法重载来指定要释放的入口数。

Semaphore 类不对 WaitOneRelease 调用强制线程标识。程序员负责确保线程释放信号量的次数不能太多。例如,假定信号量的最大计数为 2,并且线程 A 和线程 B 同时进入信号量。如果线程 B 中的编程错误导致它两次调用 Release,则两次调用都成功。这样,信号量的计数已满,当线程 A 最终调用 Release 时便会引发 SemaphoreFullException

信号量分为两种类型:局部信号量和已命名的系统信号量。如果您使用接受名称的构造函数创建 Semaphore 对象,则该对象与具有该名称的操作系统信号量关联。已命名的系统信号量在整个操作系统中都可见,可用于同步进程活动。您可以创建多个 Semaphore 对象来表示同一个已命名的系统信号量,也可以使用 OpenExisting 方法打开现有的已命名系统信号量。

局部信号量仅存在于您的进程内。您的进程中任何引用局部 Semaphore 对象的线程都可以使用它。每个 Semaphore 对象都是一个单独的局部信号量。

示例

下面的代码示例创建一个最大计数为 3、初始计数为 0 的信号量。该示例启动五个线程,这些线程阻止该信号量的等待。主线程使用 Release(Int32) 方法重载,以便将信号量计数增加为其最大值,从而允许三个线程进入该信号量。每个线程都使用 System.Threading.Thread.Sleep 方法等待一秒钟以便模拟工作,然后调用 Release 方法重载以释放信号量。每次释放信号量时,都显示前一个信号量计数。控制台消息对信号量的使用进行跟踪。每个线程的模拟工作间隔都稍有增加,以使输出更为易读。

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()); } }

你可能感兴趣的:(thread,sql,server,Semaphore,C#,resources,output)