《浅谈线程池》笔记


线程池
其实“线程池”就是用来存放“线程”的对象池。

线程池的作用
因为创建一个线程的代价较高,因此我们使用线程池设法复用线程。就这样,在一个“池”中,保存了一组可以反复使用的线程对象,从而可以节省创建线程的开销。

在.NET当中,虽然每次创建的SqlConnection对象是新的,但是这个对象内部所占用的“数据库连接”还是会复用。而用完 SqlConnection对象后的及时“关闭”(Dispose或Close),其实并没有断开数据库连接,只是把这个连接放回了连接池。

CLR线程池
在.NET中,CLR线程 操作系统线程 对应
您可以简单地认为.NET中的Thread对象便封装了一个操作系统线程,并附加了所需的数据。而CLR线程池便是存放这些CLR线程的对象池。

由于.NET自带的线程池在底层通过win32api调用的windows的进程附带的线程池,所以对于进程,这个线程池是唯一的。很多.NET自身的操作也需要通过CLR线程池来完成,比如Timer。

注意:Thread对象只有当真正Start了之后,CLR才会创建一个操作系统线程与它绑定。

CLR线程池限制了线程的创建速度不超过每秒2个。


CLR线程池的作用:
1> 可以使用ThreadPool类的两个静态方法:QueueUserWorkItem 和 UnsafeUserQueueWorkItem 向CLR线程池中添加任务(一个WorkCallback委托对象)。
2> ASP.NET在得到一个请求后,也会将这个请求处理的任务交由CLR线程池在有空闲线程的时候得以执行。
3> ThreadPool.RegisterWaitForSingleObject 方法或是System.Threading.Timer 组件也会依赖CLR线程池。


如何设置ASP.NET的线程数

  > 最大值
      对于ASP.NET应用程序来说,CLR线程池容量代表了应用程序最多可以同时执行的请求数量。对于托管在IIS上的ASP.NET执行环境来说,这个值由全局配置决定。这个配置在machine.config文件中system.web/processModel节点中,为maxWorkerThreads属性,它决定了为单个处理器分配的线程数。如果这个值为40,且机器上拥有4个处理器(2 * 2CPU),那么这台机器目前的配置表示在同一时刻,ASP.NET可以同时处理160个请求。某些参考资料建议您将其修改为每处理器80-100个线程,这时您只要修改相应的属性值就可以了。

  > 最小值
      而在ASP.NET应用程序中,其machine.config配置文件的system.web/processModel节点的 minWorkerThreads属性值,它代表了CLR线程池“总是会保留”的最少线程数量。在普通应用程序中这个值为“处理器数 * 1”。

注意:对于processModel节点的数据,ASP.NET只会读取 machine.config中的全局配置信息,这意味着我们不能使用web.config为不同应用程序配置不同的参数。如果我们要实现应用程序级别的配置,那么必须使用ThreadPool类中提供的API进行设置。


IO线程池
几乎所有的异步功能都依赖于线程池。
通常所说的IO线程池,便是为异步IO服务的线程池。


   同步IO
      若无IO线程池,则可能需要通过同步访问IO(即直接访问IO),其最简单的方式便是阻塞,如:读取一个文件。代码会等待IO操作成功(或失败)之后才继续执行下去,一切都是顺序的。

   异步IO
      在使用异步IO时,访问IO的线程不会被阻塞,逻辑将会继续下去。操作系统会负责把结果通过某种方法通知我们,一般说来,这种方式是“回调函数”。异步IO在执行过程中是不占用应用程序的线程的,因此我们可以用少量的线程发起大量的IO,所以应用程序的响应能力也可以有所提高。


IOCP
Windows操作系统中有多种异步IO方式,但是性能最高,伸缩性最好的方式莫过于“IO完成端口(I/O Completion Port,IOCP)”,这也是.NET中封装的唯一一个对IO操作的异步IO方式。CLR会为每个进程创建一个IOCP(I/O Completion Port)并和Windows操作系统一起维护。


备注:关于CLR线程的使用与创建,以及CLR线程池与IO线程池是否有关系等,请看《浅谈线程池(下):相关试验及注意事项》中的示例。


学习来源:
浅谈线程池(上):线程池的作用及CLR线程池

浅谈线程池(中):独立线程池的作用及IO线程池

浅谈线程池(下):相关试验及注意事项

原文地址:https://www.cnblogs.com/xugang/p/1669592.html