首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【推荐】C#线程篇---你所不知道的线程池(4)

【推荐】C#线程篇---你所不知道的线程池(4)

作者头像
逸鹏
发布2018-04-10 16:43:32
1.5K0
发布2018-04-10 16:43:32
举报
文章被收录于专栏:逸鹏说道逸鹏说道

线程的创建和销毁都要耗费大量的时间,有什么更好的办法?用线程池!

太多的线程浪费内存资源,有什么更好的办法?用线程池!

太多线程有损性能,有什么更好的办法?用线程池!(⊙_⊙)?

线程池是什么?继前三篇线程基础之后,我们要来学学线程池了。注意,这些信息相当有用!

为了设计和实现可伸缩的可响应的和可靠的应用程序或组建,线程池是你必须采用的核心技术。

线程池是CLR的,线程池自动为你管理线程的创建和销毁,线程池创建的一组线程将为各种任务而重用,极大提高了使用线程的成本,这也就意味着,你的应用程序其实只需要几个线程即可完成全部工作。

大概的讲了一下,来看看线程池的细节:

  大家可以想象一下:一个应用程序就好比一个抽屉,抽屉里面放了你分好类的东西,抽屉里面的"某一个东西"就好比这个应用程序的线程集合,这个抽象集合就是一个CLR。假如要抢救财物,你会选择拿抽屉里的东西还是拿抽屉呢?

好了,有了模型就好介绍CLR了,每个CLR都有它自己的线程池,这个线程池在应用程序域中共享。如果一个进程中加载了多了CLR,那么每个CLR都有它自己的线程池,有点抽象(─.─|||,很难解释清楚- -。多看几次,会领会这个意思的。)

  CLR在初始化的时候,线程池中没有是线程的。它的内部,线程池维护着一个操作请求队列。在应用程序想执行一个异步操作时,就会有发送一个需要调用某个方法的”记录项“,这个“记录项”会追加到线程池的队列中,然后线程池的代码从这个记录项中提取记录,为记录项分配给一个线程池线程。如果线程池中没有线程,就创建一个新的线程。

  创建线程会消耗一些资源(前面提到过了),当线程完成任务之后,线程不会被销毁,它从哪里来回哪里去(回到线程池,在那里进入空闲状态,等待下一次命令),由于线程不会被销毁,所以不再产生额外的性能损失。

  现在疑问来了!如果应用程序发出许多请求,会怎么办?

  线程池会尝试只用一个线程来服务所有的请求。然而,如果应用程序发出请求的速度超过了线程池处理它们的速度,线程池就会十分人性话的加”雇用兵“,创建额外的线程。到最后,应用程序的有请求都能由少量线程处理,不会存在太多的线程,不会浪费额外的性能。

  现在我们又会觉得,如果线程池真的有很多“雇佣兵”了,怎么办? 不照样是浪费了吗?

  其实这个已经考虑了,一个“雇佣兵”太久接不到活怎么办?空闲的线程多了,线程会自己醒来,来终止自己以释放资源。

  不是吧?终止线程也会产生性能损失啊!说好的解决性能损失呢??

  哈哈,线程闲的蛋疼了,还有什么性能损失?这表明应用程序已经没有在做什么事情了,所以这个性能损失,问题不大。

  再来扯扯线程池概念,让大家易于理解。

  线程池可以只容纳少量线程,从而避免资源浪费;也可以容纳更多线程,以利用多处理器,超线程处理器和多核处理器。它能在这两种不同的状态之间从容切换。

  线程池是启发式的。只要硬件支持,比如有多个CPU,线程池就会创建更多的线程。如果应用程序的负载减轻,线程池线程就会终结它们自己。

  线程池讲自己的线程划分为工作者线程和I/O线程。工作者线程是执行异步操作的执行线程,而I/O线程则用于通知你一个异步操作任务已经完成。

写了一大串概念性的东西,来使用一下线程池吧^_^。

  初用线程池,执行简单的计算限制操作:

static void Main(string[] args)
        {
            Console.WriteLine("主线程启动");
            ThreadPool.QueueUserWorkItem(StartCode,5);
            Console.WriteLine("主线程运行到此!");
            Thread.Sleep(1000);
        }


        private static void StartCode(object i)
        {
            Console.WriteLine("开始执行子线程...{0}",i);
            Thread.Sleep(1000);//模拟代码操作
 
 
        }

这个和第一篇的那个列子很相似。也很简单。要说的是,QueueUserWorkItem()中的参数:

必须匹配这个委托,我这个示例是用的第二个方法。

结果就像这样:

我的是双核处理器,主线程和子线程是同时运行的。

如果是单核的话,结果可能就不同了,因为这是Windows调试器决定先调度哪个线程控制不了~~~~

这主要介绍线程池,就这么多了。^_^

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 我为Net狂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档