当前位置:  开发笔记 > 开发工具 > 正文

线程与ThreadPool

如何解决《线程与ThreadPool》经验,为你挑选了4个好方法。

使用新线程和使用线程池中的线程有什么区别?有什么性能优势,为什么我应该考虑使用池中的线程而不是我明确创建的线程?我在这里专门讨论.NET,但一般的例子很好.



1> Karg..:

线程池将为频繁和相对较短的操作提供好处

重用已经创建的线程而不是创建新线程(一个昂贵的过程)

当有新的工作项请求突发时,限制线程创建的速度(我相信这仅在.NET 3.5中)

如果排队100个线程池任务,它将只使用已经创建的线程来为这些请求提供服务(例如10个).线程池将进行频繁检查(我相信3.5 SP1中每500ms),如果有排队任务,它将创建一个新线程.如果您的任务很快,那么新线程的数量将会很少,并且重新使用10个左右的线程来完成短任务将比预先创建100个线程更快.

如果您的工作负载始终存在大量线程池请求,则线程池将通过上述过程在池中创建更多线程来调整自身以适应您的工作负载,以便有更多可用于处理请求的线程

有关线程池如何在引擎盖下运行的详细信息,请查看此处

如果作业运行时间相对较长(可能大约一两秒,但这取决于具体情况),自己创建一个新线程会更合适

@Krzysztof - 线程池线程是后台线程,它将在主线程结束时停止.默认情况下,手动创建的线程是前台(在主线程结束后将继续运行),但在调用Start之前可以设置为后台.


我唯一想知道的是来自MSDN的以下声明(http://msdn.microsoft.com/en-us/library/1c9txz50.aspx)"后台线程仅在执行的前台线程数小于处理器的数量." 那么这是否意味着当在前景线程获得优先权的核心之间进行分工时?

2> Martin..:

.NET托管的线程池: -

根据当前工作负载和可用硬件确定大小

包含工作线程完成端口线程(专门用于服务IO)

针对大量相对短暂的操作进行了优化

存在其他可能更适合长时间运行的线程池实现.

具体来说,使用线程池来防止您的应用程序创建太多线程.线程池最重要的特性是工作队列.也就是说,一旦您的计算机足够繁忙,线程池将排队请求而不是立即生成更多线程.

所以,如果你要创建一个小的,有限数量的线程自己创建它们.如果您无法预先确定可以创建多少线程(例如,它们是为响应传入的IO而创建的),并且它们的工作将是短暂的,请使用线程池.如果您不知道有多少,但他们的工作将长期运行,平台中没有任何东西可以帮助您 - 但您可能能够找到适合的替代线程池实现.



3> 小智..:

new Thread().Start()

产生前景线程,如果你关闭你的程序将不会死亡.ThreadPool线程是关闭应用程序时死亡的后台线程.


关于"计划"一词的澄清.桌面应用程序在进程中运行,并且至少有一个前台线程来管理UI.只要它具有前台线程,该过程将继续运行.当您关闭桌面应用程序时,前台UI线程会停止,但如果它有其他前台线程,则您不一定*停止进程*.
您始终可以将线程设置为背景.它们默认只是前景.
nemo:var t = new Thread(...); t.BackgroundThread = true; t.Start();

4> PeterM..:

我对这些的相对资源使用感到好奇,并在我的2012双核英特尔i5笔记本电脑上使用.net 4.0发布版本在Windows 8上运行基准测试.线程池平均花费0.035毫秒开始,线程平均花费5.06女士.换句话说,对于大量短期线程,池中的线程开始快了大约300倍.至少在测试范围(100-2000)个线程中,每个线程的总时间似乎非常不变.

这是基准测试的代码:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

在此输入图像描述


我认为这是因为ThreadPool重用创建的线程而不是创建新的线程(价格昂贵)
推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有