原文地址:http://www.theukwebdesigncompany.com/articles/iocp-thread-pooling.php

PartOne : Introduction

当使用C#构建服务器端应用时,创建线程池是一个十分重要的能力。线程池允许服务器端程序通过队列最大程度的处理任务。除了构建线程池之外,还有两个方案:

1.        使用单线程处理所有的任务。

2.        当任务需要时就产生子线程来处理任务。

本文定义任务为需要处理的事件,这些工作也许是也许不是分布式的数据。目标是以最高的效率和最短的时间处理这些任务。

首先是一个通用的原则,如果可以用单线程处理所有任务,那么使用单线程。如果同时使用多线程处理任务是不必要的,意味着应用程序有更多的事情要做,或者单线程处理更快。比如当多个线程请求同一资源时,会产生阻塞,必须等待前面的线程处理完之后才可以获取资源,完成任务处理。在发生阻塞时,等待的线程会进入休眠状态,不做任何工作。但是实际上这些线程会对操作系统产生很大的负担。操作系统必须监控任务处理情况,当资源释放时,决定唤醒哪个线程进行处理。如果需要处理任务的线程因为等待资源而处于休眠状态,这样我们就需要处理这个任务。在这种情况下可以将这些线程放入队列,并用单个线程处理这个队列。

最先等待资源的线程不一定先得到资源,如图-1所示。

图-1 线程示例图

如果任务之间是相互独立的,这儿的相互独立是指不会发生资源冲突,在处理多任务时可以产生多个线程来处理不同的任务。此时的问题是操作系统,比如windows操作系统,运行多个线程时,需要等待CPU。Windosw操作系统需要管理所有的线程,而UNIX操作系统则不需要。如果有大量线程同时运行,系统性能将会大大降低。

在.net框架,“system.Threading”命名空间内有一个ThreadPool类。不幸的是这个类是一个静态类,只能有一个线程池。这个线程池不允许设定线程的并发级别。不同的并发级别允许并发的线程不同。如果我们设置合适的并发级别,我们会得到最高的效率。

假设我们有一个可以允许4个线程并发级别为1的线程池。然后有三个任务发送给线程池处理。只能有一个线程处理任务,其他的线程都处在等待状态。如图-2。

图-2 线程池

那么当并发级别设置为1时,如果运行多个线程?如果图-2 中的线程1 进行休眠,线程池将会启动另外一个线程。如图-3。

图-3

突然的线程1 被唤醒,线程4很有可能还没有结束。这样我们就有了两个线程同时运行,虽然并发级别仍然为1.如图-4。

图-4

其他的线程只有等这两个线程都进入休眠状态才能运行。即使并发级别限制活动线程池中在任意给定时间的数量,我们可以有更多的活动线程然后并发级别允许。这一切都取决于池中的线程的状态,以及如何快速的线程可以完成,他们正在处理的工作。

一个好的设置并发级别的策略是按照系统的CPU的数量进行设置。如果CPU处在空闲状态,此时有任务需要处理,则启动一个新的线程来处理任务。如果CPU忙,则不会新建线程。同时我们需要注意,不要让一个线程长时间的处于休眠状态,这会导致所有的线程池都处在激活状态,影响线程池的效率和服务器的效率。

下面会介绍如何添加 IOCP线程池到应用中。

Part2: Defining the Solution

略。

C# 中的IOCP线程池的更多相关文章

  1. 详解线程池的作用及Java中如何使用线程池

    服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...

  2. 聊聊面试中的 Java 线程池

    ​背景 关于 Java 的线程池我想大家肯定不会陌生,在工作中或者自己平时的学习中多多少少都会用到,那你真的有了解过底层的实现原理吗?还是说只停留在用的阶段呢?而且关于 Java 线程池也是在面试中的 ...

  3. Python中如何使用线程池和进程池?

    进程池的使用 为什么要有进程池?进程池的概念. 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务. 那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程 ...

  4. Spring Boot中如何配置线程池拒绝策略,妥善处理好溢出的任务

    通过之前三篇关于Spring Boot异步任务实现的博文,我们分别学会了用@Async创建异步任务.为异步任务配置线程池.使用多个线程池隔离不同的异步任务.今天这篇,我们继续对上面的知识进行完善和优化 ...

  5. 从源代码分析Universal-Image-Loader中的线程池

    一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可 ...

  6. android中对线程池的理解与使用

    前段时间有幸接到腾讯上海分公司的 Android开发面试,虽然最后一轮被毙了.但还是得总结一下自己在android开发中的一些盲点,最让我尴尬的是面试官问我几个android中线程池的使用与理解..哎 ...

  7. Universal-Image-Loader完全解析--从源代码分析Universal-Image-Loader中的线程池

    一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可 ...

  8. 探究ElasticSearch中的线程池实现

    探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...

  9. Java中线程池的实现原理

    知识点总结 ---------------------------------------------------------------------------------------------- ...

随机推荐

  1. 为什么TCP连接不可靠

    原文链接:http://watter1985.iteye.com/blog/1924977 原文在此 这篇文章是关于TCP网络编程的一个不起眼的小问题.几乎人人都并不太明白这个问题是怎么回事.曾经我以 ...

  2. select 通过jq赋值

    <select name="F_YSBAQLX" onchange="selectvalue()" id="lista" prompt ...

  3. Java笔记4-do while循环,break,修饰符,方法的调用

    do while循环语法:do{ //循环体}while(条件表达式); 注:它是先执行循环体,后再判断的循环结构. 如:int i = 0;do{ System.out.println(" ...

  4. |原创|unity 4.3 2D功能SpriteRenderer修改颜色的方法

    4.3增加了不少2D功能,然后实在没有找到有人分享,在国外查资料研究一下午然后给个简单的教程 ===================================================== ...

  5. <<有效软件测试>> 读书笔记和自己的一些思考

    需求阶段 1. 测试人员及早介入,需要彻底了解产品,设计测试过程 * 及早介入,可以了解在开发的过程中需要使用哪些新技术,新的平台, 测试组是否方便进行测试,是否方便进行自动化测试,早期开发和测试应该 ...

  6. SQL Server2005作业执行失败的解决办法

    数据库:SQL Server 2005,运行环境:Windows Server 2008  在数据库里的所有作业都执行失败,包括自动执行和手动执行.在事件查看器里看到的错误报告如下: 该作业失败.  ...

  7. decimal,float和double的区别

    http://www.cnblogs.com/yellowapplemylove/archive/2011/08/23/2150316.html 一直很奇怪C#的预定义数据类型中为什么加了一个deci ...

  8. js中this的问题

    Javascript的this用法 this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, function test(){ ; } 随 ...

  9. ORACLE创建表之前判断表是否存在与SQL Server 对比使用

    在SQL Server 数据库中,我们在创建表之前删除表,有if exit()这样的语句,但是在oracle中却没有.如果直接使用drop table那么如果表不存在会报错,导致后续语句无法运行.因此 ...

  10. 异步编程 z

    走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...