Web常用工具 二维码美化 在线压缩 JavaScript AI工具汇总网站 ASP.NET控件源码查询 W3CHTML W3SCHOOL 开源中国 51aspx github codeproject SQLBACKUP 几种排序算法比较 SQL中deny权限 MSDN下载 HttpWebRequest类 HTML5 stackoverflow ASP.NET 页生命周期概述 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 [SQL Server]视图sys.sysprocesses brnshop学习 SQL视频 Fiddler帮助文档 Sprint.Net SQLServer牛人博客 codeplex IIS官网 IE11 Developer Jquery源码视频上 Jquery源码视频下 Jquery Bugs jquery.miaov.com 正则表达式 Jquery API 1.9 Service Broker Javascript Object中的方法讲解 Microsoft webcast 微信开发接口 ECMAScript5 Underscore Jquery Bugs SQL存储过程事务嵌套 官网SQL事务锁 2345天气插件 Json数据查看 C++ jquery-plugin-validate 博学谷(传智播客) Swift视频 IOS代码论坛 SWIFT设计模式 操作系统下载 AngularJS VueJS ASPNETCORE 前端题库 Node.js ASPNETCORE 腾讯课堂 SwiftUI SwiftUI疑问解答 ADO.NET SMO 数字化企业网 Unicode码查询 Redis使用文档 .NET 微服务:适用于容器化 .NET 应用程序的体系结构 .NETCore5.0微软官方文档 CSS3.0 在 ASP.NET Core 中配置 Windows 身份验证 Maven使用教程 Maven Repository Thymeleaf Thymeleaf中文CSDN Spring官方文档 Spring中文文档 SpringBoot SpringData SVG在线设计工具 SVG教程01 SVG教程02 fontawesome图标库 mybatis官网 mybatis-spring中文 mysql教程 python教程 python的scrapy教程01 python的scrapy教程02 VS开发python xpath教程 腾讯向量数据库教程 JSZip浏览器内存中创建文件与文件夹 axios的使用文档 SheetJS(JS操作excel)的使用文档

huaan011

 

基元线程同步构造之信号量(Semaphore)

  信号量(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个空闲的位置,可以执行线程了。

 这只是自己的理解,不正确的望各位大侠们指教。。。。。。。。。。。。。。。

 

posted on 2014-03-03 16:41  华安  阅读(405)  评论(0编辑  收藏  举报

导航