信号量(semaphore)不过是由内核维护的 int32变量而已,(说通俗点就是好比一个线程容器里面允许执行的线程数,0计数就是允许执行的0个线程数,1就是允许执行的1个线程数,2就是允许执行的2个线程数,等等一次类推。。。。。。,0就是当前执行的线程数占满了容器没空余的了)。
当信号量为0时,在信号量上等待的线程会全部阻塞;
当信号量大于0时,就解除阻塞。
在一个信号量上等待的一个线程解除阻塞时,内核自动从信号量的计数中减1,线程运行完后调用Release,计数就加1。信号量还关联了一个最大的Int32值,当前计数绝不允许超过最大计数。下面展示了semaphore类的样子:
public sealed class Semaphore :WaitHandle{ //初始化信号量:初始请求数为initialCount,最大请求数为maximumCount public Semaphore(Int32 initialCount,Int32 maximumCount); public Int32 Release();//调用Release(1);返回上一个计数 public Int32 Release(Int32 releaseCount);//返回上一个计数 }
initialCount:就是初始化信号量时,解除阻塞的线程数。
maximumCount:就是信号量允许执行的最大线程数。
一个自动重置事件在行为上和最大计数为1的信号量非常相似。两者的区别在于,可以在一个自动重置事件上连续多次调用Set,同时仍然只有一个线程解除阻塞。相反,在一个信号量上连续多次调用Release,会使它的内部计数一直递增,这可能解除大量线程的阻塞。如果在一个信号量上多次调用Release,会导致它的计数超过最大计数,这是Release会抛出一个SemaphoreFullException.
请看MSDN中的一个例子:
1 using System; 2 using System.Threading; 3 4 public class Example 5 { 6 // A semaphore that simulates a limited resource pool. 7 // 8 private static Semaphore _pool; 9 10 // A padding interval to make the output more orderly. 11 private static int _padding; 12 13 public static void Main() 14 { 15 // Create a semaphore that can satisfy up to three 16 // concurrent requests. Use an initial count of zero, 17 // so that the entire semaphore count is initially 18 // owned by the main program thread. 19 //初始化时允许解除的阻塞线程数量为0,最大的执行线程数为3,所以在第执行完第44行代码之前,开启的子线程中的代码都不会执行,如果注释掉第45行代码,这5个子线程都不会执行,如果改成:new Semaphore(1,3)初始化时允许解除的阻塞线程数量为1,最大执行的线程数为3,所以在执行完31行代码后会有一个子线程在运行的,如果注释掉第45行代码,就会只有一个信号量慢慢的运行完这5个子线程 20 _pool = new Semaphore(0, 3); 21 22 // Create and start five numbered threads. 23 // 24 for (int i = 1; i <= 5; i++) 25 { 26 Thread t = new Thread(new ParameterizedThreadStart(Worker)); 27 28 // Start the thread, passing the number. 29 // 30 t.Start(i); 31 } 32 33 // Wait for half a second, to allow all the 34 // threads to start and to block on the semaphore. 35 // 36 Thread.Sleep(500); 37 38 // The main thread starts out holding the entire 39 // semaphore count. Calling Release(3) brings the 40 // semaphore count back to its maximum value, and 41 // allows the waiting threads to enter the semaphore, 42 // up to three at a time. 43 // 44 Console.WriteLine("Main thread calls Release(3)."); 45 _pool.Release(3);//此句代码的通俗意思就是重新再增加3个可以执行的线程,如果初始化new semaphore(1,5)运行完这代代码就是1+3=4个线程数解除阻塞了,如果初始化为new semaphore(0,5)运行完这段代码就是0+3=3个线程数解除阻塞了。 46 //Console.WriteLine("_pool {0}", _pool.Release()); 47 //Console.WriteLine("_pool {0}", _pool.Release()); 48 //Console.WriteLine("_pool {0}", _pool.Release()); 49 //Console.WriteLine("_pool {0}", _pool.Release()); 50 //Console.WriteLine("_pool {0}", _pool.Release()); 51 52 Console.WriteLine("Main thread exits."); 53 54 // Thread.Sleep(5000); 55 // Console.WriteLine("_pool {0}", _pool.Release()); 56 57 Console.ReadLine(); 58 } 59 60 private static void Worker(object num) 61 { 62 // Each worker thread begins by requesting the 63 // semaphore. 64 Console.WriteLine("Thread {0} begins " + 65 "and waits for the semaphore.", num); 66 _pool.WaitOne(); 67 68 // A padding interval to make the output more orderly. 69 int padding = Interlocked.Add(ref _padding, 100); 70 71 Console.WriteLine("Thread {0} enters the semaphore.", num); 72 73 // The thread‘s "work" consists of sleeping for 74 // about a second. Each thread "works" a little 75 // longer, just to make the output more orderly. 76 //模拟阻塞线程 77 Thread.Sleep(1000 + padding); 78 79 Console.WriteLine("Thread {0} releases the semaphore.", num); 80 Console.WriteLine("Thread {0} previous semaphore count: {1}", 81 num, _pool.Release()); 82 } 83 } 运行的其中之一的一个结果为:
Thread 2 begins and waits for the semaphore.
Thread 3 begins and waits for the semaphore.
Thread 4 begins and waits for the semaphore.
Thread 1 begins and waits for the semaphore.
Thread 5 begins and waits for the semaphore.
Main thread calls Release(3).
Thread 5 enters the semaphore.
Thread 5 releases the semaphore.
Thread 5 previous semaphore count: 0
Thread 1 enters the semaphore.
Thread 1 releases the semaphore.
Thread 1 previous semaphore count: 0
Thread 3 enters the semaphore.
Thread 3 releases the semaphore.
Thread 3 previous semaphore count: 0
Main thread exits.
Thread 2 enters the semaphore.
Thread 2 releases the semaphore.
Thread 2 previous semaphore count: 1 //执行这段代码前。信号量(semaphore)中还有两个线程在执行(当前运行运行的线程和下面还没运行完的一个线程,所以剩余1个线程的信号量(semaphore)可以执行.
Thread 4 enters the semaphore.
Thread 4 releases the semaphore.
Thread 4 previous semaphore count: 2 //执行这段代码前。信号量(semaphore)中有2个空闲的位置,可以执行线程了。
这只是自己的理解,不正确的望各位大侠们指教。。。。。。。。。。。。。。。
基元线程同步构造之信号量(Semaphore),布布扣,bubuko.com
原文:http://www.cnblogs.com/huaan011/p/3578652.html