C# 中的IOCP线程池
原文地址: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线程池的更多相关文章
- 详解线程池的作用及Java中如何使用线程池
服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...
- 聊聊面试中的 Java 线程池
背景 关于 Java 的线程池我想大家肯定不会陌生,在工作中或者自己平时的学习中多多少少都会用到,那你真的有了解过底层的实现原理吗?还是说只停留在用的阶段呢?而且关于 Java 线程池也是在面试中的 ...
- Python中如何使用线程池和进程池?
进程池的使用 为什么要有进程池?进程池的概念. 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务. 那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程 ...
- Spring Boot中如何配置线程池拒绝策略,妥善处理好溢出的任务
通过之前三篇关于Spring Boot异步任务实现的博文,我们分别学会了用@Async创建异步任务.为异步任务配置线程池.使用多个线程池隔离不同的异步任务.今天这篇,我们继续对上面的知识进行完善和优化 ...
- 从源代码分析Universal-Image-Loader中的线程池
一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可 ...
- android中对线程池的理解与使用
前段时间有幸接到腾讯上海分公司的 Android开发面试,虽然最后一轮被毙了.但还是得总结一下自己在android开发中的一些盲点,最让我尴尬的是面试官问我几个android中线程池的使用与理解..哎 ...
- Universal-Image-Loader完全解析--从源代码分析Universal-Image-Loader中的线程池
一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可 ...
- 探究ElasticSearch中的线程池实现
探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...
- Java中线程池的实现原理
知识点总结 ---------------------------------------------------------------------------------------------- ...
随机推荐
- 基于cocos2d-x的Android游戏中使用fmod音频引擎
cocos2d-x的音频引擎是cocosDenshion, 它的Android版比较弱, 只能播放一个背景音乐和些许音效, 如果要实现稍微复杂一点的音频播放, 比如同时播放几个音轨就不能了. 这一点远 ...
- 关于在win7内集成usb3.0驱动。
mac air 装了win7但是折腾良久还是无法升级,只能是重新安装. 很蛋疼.bootcamp 老是找不到驱动.只能是手动分区后U盘引导安装. 驱动的下载,直接在Os x 下用bootcamp 下载 ...
- python数据结构与算法——完全树 与 最小/大堆
# 完全树 最小堆 class CompleteTree(list): def siftdown(self,i): """ 对一颗完全树进行向下调整,传入需要向下调整的节 ...
- C++中的迭代器
C++STL中的迭代器 "指针"对所有C/C++的程序员来说,一点都不陌生.在接触到C语言中的malloc函数和C++中的new函数后,我们也知道这两个函数返回的都是一个指针,该指 ...
- UVa 二叉树重建(先序+中序求后序)
题意是给出先序和中序,求出后序. 先序遍历先访问根结点,通过根结点可以在中序中把序列分为左子树部分和右子树部分,我建了一个栈,因为后序遍历最后访问根结点,所以把每次访问的根结点放入栈中.因为后序遍历先 ...
- // 开始无限播放 ViewPager
public class MainActivity extends Activity { private ViewPager vp; private Handler handler = new ...
- JS(去掉前后空格或去掉所有空格)的用法 推荐使用jquery 方法
说明: 如果使用jQuery直接使用$.trim(str)方法即可,str表示要去掉前后所有空格的字符串. 推荐 1. 去掉字符串前后所有空格: 代码如下: function Tri ...
- javascript中的对象之间继承关系
相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象 ...
- Eclipse下新建Maven项目、自动打依赖jar包
当我们无法从本地仓库找到需要的构件的时候,就会从远程仓库下载构件至本地仓库.一般地,对于每个人来说,书房只有一个,但外面的书店有很多,类似第,对于Maven来说,每个用户只有一个本地仓库,但可以配置访 ...
- windows下用一台机器配置分布式redis(主从服务器)
目录1.Replication的工作原理2.如何配置Redis主从复制 1.Replication的工作原理在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启 ...