为什么线程池以这种方式管理线程
本文关键字:线程 方式 管理 为什么 | 更新日期: 2023-09-27 18:32:57
Joe Albahari 在他的 C# 线程电子书中很好地解释了 .NET Thread Pool 的自动线程管理,以及为什么它以这种方式工作。
据我了解,默认情况下,在占用处理器的所有内核后,线程池会延迟新线程的创建,因为如果所有处理器内核都忙于进行计算,创建新线程将无法再提高应用程序的整体吞吐量(每秒完成的任务(,新线程只是浪费系统资源。
但是,如果任务在线程池队列中停留的时间过长,则线程池会假定池化线程处于空闲状态或以某种方式阻塞,并尝试通过并发运行任务来利用停机时间。
在许多情况下,采用一种技术,使线程池线程具有指示"等待"状态的特殊属性,而不是这种"延迟"算法,这不是更有意义吗?它可能看起来像这样:
System.Threading.Thread.CurrentThread.IsWaiting = true;
线程池将立即为排队的任务创建新线程,直到所有处理器内核都被非等待线程占用。然后,任务将保留在队列中,直到线程完成或发出等待状态的信号。
这将有几个好处。首先,如果处理器内核处于空闲状态,则任务始终在排队进入池的那一刻启动,没有延迟。其次,在运行大量计算密集型任务(需要半秒以上才能完成(的应用程序中,线程池不会继续给系统带来不必要的额外线程负担。
当然,在某些情况下,应用程序需要在严格的截止日期内完成任务,并且不能等待其他任务先完成。此算法可能不适用于这些应用程序。否则,我认为它只会提高多线程应用程序的效率。
你觉得怎么样?
我们在 Thread.ThreadState
属性中提供了此信息。但是,线程池使用此信息并不是一个好主意。要使用它,我们需要线程之间的通信(线程池中的线程和另一个收集信息的线程(。这意味着需要一些同步,或者至少是易失性的访问。两者都非常昂贵。因此,我们会给 ThreadPool 的所有应用程序带来运行时负担,而只有少数应用程序会受益。
作为一名程序员,你必须反映你的线程池是如何被使用的。如果标准行为不适合您,您可以调整池。例如,使用ThreadPool.SetMinThreads
,如果你知道你有很多等待线程。它不会像您希望的那样自动。但是您的自动化也不是完美的,因为当一些等待的线程同时唤醒时,我们很容易运行太多线程。
请注意,其他线程池根本没有非常聪明的扩展启发式,它是内置于 C# 变体中的。通常,您有固定数量的正在运行的线程,并且您运行的线程数永远不会超过此数量。