在线程池外创建线程有什么好处?

时间:2015-09-02 11:53:58

标签: c# .net multithreading asynchronous task

好的,所以我想知道当我使用TaskCreationOptions.LongRunning时会发生什么。通过this回答,我开始知道对于长时间运行的任务,我应该使用这个选项,因为它在线程池之外创建一个线程。

冷却。但是当我在线程池外创建一个线程时,我会得到什么好处?什么时候做,避免它?

2 个答案:

答案 0 :(得分:4)

  

在线程池外创建线程时,我会获得什么好处?

线程池,就其命名状态而言,是一个线程池,它被分配一次并在整个过程中重复使用,以节省分配线程所需的时间和资源。游泳池本身按需重新调整大小。如果您排队的工作量超过池中存在的实际工作人员,则它将以500毫秒的间隔分配更多线程,一次一个(这样可以避免同时分配多个线程,其中现有线程可能已经完成执行并可以处理请求)。如果在线程池上执行了许多长时间运行的操作,则会导致“线程饥饿”,这意味着代理将开始排队并仅在线程释放后运行。这就是为什么你要避免大量线程使用线程池线程进行冗长的工作。

The Managed Thread-Pool docs也有关于此问题的部分:

  

有几种情况适合创建和   管理自己的线程而不是使用线程池线程:

     
      
  • 您需要一个前台线程。
  •   
  • 您需要一个具有特定优先级的线程。
  •   
  • 您的任务导致线程长时间阻塞。线程池有最大线程数,所以一个大的   被阻塞的线程池线程数可能会阻止任务   开始。
  •   
  • 您需要将线程放入单线程单元中。所有ThreadPool线程都在多线程单元中。
  •   
  • 您需要具有与该线程关联的稳定标识,或者将线程专用于任务。
  •   

有关更多信息,请参阅:

答案 1 :(得分:3)

“长时间运行”可以很好地量化,需要超过半秒的线程运行时间很长。这是现代机器上的大量处理器指令,你必须每秒燃烧50亿个它们。除非你在分数中计算Pi到数千位小数的值,否则很难以建设性的方式进行。

实用线程只能在没有刻录核心但是等待时花费很长时间。总是进行I / O完成,例如从磁盘,网络和dbase服务器读取数据。通常是你开始考虑首先使用线程的原因。

线程池有一个“经理”。它确定何时允许线程池线程启动。当您在程序中启动它时,它不会立即发生 。管理器尝试将运行的线程数限制为您拥有的CPU核心数。这种方式更有效,太多活动线程之间的上下文切换是昂贵的。一个好的节流阀,可以防止你的程序在爆发时消耗太多资源。

但是线程池管理器与管理器有着非常普遍的问题,它对正在发生的事情知之甚少。就像我的经理不知道我在Stackoverflow.com上搞砸了一样,tp管理员不知道线程正在等待什么,而不是实际执行有用的工作。没有这些知识就无法做出正确的决定。应该忽略执行大量等待的线程,并且应该允许另一个线程在其位置运行。实际上是在做真正的工作。

就像你告诉你的经理你去度假,所以他可以期待没有工作要完成,你告诉线程池经理与LongRunning一样。

请注意它并不是很糟糕,因为它可能听起来像这个答案。特别是.NET 4.0聘请了一位新的经理,在确定最佳运行线程数时更加聪明。它使用反馈循环,收集数据以发现活动线程是否实际完成工作。并相应地调整最佳值。这种方法的唯一问题是当你关闭反馈循环时常见的问题,你必须使它慢,这样循环不会变得不稳定。换句话说,它在提高活动线程数方面并不是特别快。

如果您提前知道线程非常糟糕,运行许多秒而没有真正的CPU负载,那么总是选择LongRunning。否则它是一个调整工作,在程序完成时观察程序并修改它以使其更加优化。