2014-12-03 73 views
3

Joe Albahari提供了.NET Thread Pool的自动线程管理的great explanation,以及它在C#电子书中的Threading中如何工作。为什么线程池以这种方式管理线程?

根据我的理解,默认情况下,占用所有处理器的内核后,线程池会延迟新线程的创建,因为如果所有处理器内核忙于计算,则创建新线程不能再提高整体吞吐量(每秒完成的任务),新线程只是浪费系统资源。

但是,如果任务位于线程池队列中的时间太长,则线程池会假定池线程以某种方式空闲或阻塞,并尝试通过并发运行任务来利用停机时间。

而不是这个“延迟”算法,在许多情况下,使用一种技术,让线程池线程有一个特殊的属性来表示“等待”状态,这样做会更有意义吗?它可能是这个样子:

System.Threading.Thread.CurrentThread.IsWaiting = true; 

的线程池会为排队的任务立即创建新的线程,直到所有的处理器内核与非等待线程占用。然后,任务保持在队列中,直到线程完成,或者发出一个等待状态。

这会带来一些好处。首先,如果处理器内核处于空闲状态,那么任务总是在它们排队到池时立即启动,而不会延迟。其次,在一个运行大量计算密集型任务的应用程序中,完成时间超过半秒,线程池将不会继续给系统带来不必要的额外线程负担。

当然,在某些情况下,应用程序需要在严格的最后期限内完成任务,并且不能等待其他任务先完成。该算法可能不适用于这些应用程序。否则,我想这只会提高多线程应用程序的效率。

您认为如何?

+0

当然。但是这个功能并不存在,所以这只是肚脐眼。在I/O完成时让线程池线程浪费时间是一个错误。从程序中删除错误是程序员的工作,并发分析器是查找此类错误的首选工具。 – 2014-12-03 11:26:35

回答

0

我们可以在Thread.ThreadState住宿获得此信息。但是,线程池使用这些信息并不是一个好主意。要使用它,我们需要在线程之间进行通信(线程池中的和另一个收集信息)。这意味着一些同步需求,或者至少是易失性访问。两者都非常昂贵。因此,我们会给ThreadPool的所有应用程序带来运行时负担,而只有少数人会受益。

作为一名程序员,您必须反映您的线程池是如何使用的。如果标准行为不适合你,你可以调整游泳池。例如。使用ThreadPool.SetMinThreads,如果你知道你有很多等待线程。它不会像你想的那样自动。但是你的自动化也不是完美的,因为当一些等待线程同时唤醒时,我们可能会有太多线程在运行。

请注意,其他线程池根本没有非常聪明的扩展heurisitc,它构建在C#变体中。通常情况下,您拥有固定数量的正在运行的线程,并且永远不会超过此数字。