【问题标题】:What's the difference between using the thread pool and a normal thread?使用线程池和普通线程有什么区别?
【发布时间】:2010-11-06 17:01:15
【问题描述】:

我在 SO 上阅读随机问题和答案时遇到了这个问题:

C#, IAsyncResult and the thread pool

问题是X方法使用线程池还是使用普通线程。

使用线程池和普通线程有什么区别?

【问题讨论】:

    标签: .net multithreading


    【解决方案1】:

    线程池创建线程并将工作分配给空闲线程。这种为每个工作项创建和释放线程的方式是预防性的,因为创建和释放线程是一项相对昂贵的操作。

    【讨论】:

      【解决方案2】:

      ThreadPool 包含许多可供您使用的线程,这可能会消除创建新线程的成本,这就是您创建普通线程时发生的情况。

      【讨论】:

        【解决方案3】:

        线程池通常适用于短时间运行的任务。它的局限性在于它是一个应用程序范围的有限资源(每个 CPU 25 个),并且有很多内部类使用线程池,因此如果您执行大量长时间运行的任务,您将耗尽所有线程。

        对于长时间运行的任务,最好使用手动创建的线程,并将其背景属性设置为 true。

        注意:在 .NET Framework 2.0 版中,Thread.CurrentPrincipal 属性值传播到使用 QueueUserWorkItem 方法排队的工作线程。在早期版本中,不传播主体信息。

        何时不使用线程池线程

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

        • 您需要一个前台线程(!)。

        • 您需要线程具有特定的优先级。

        • 您的任务会导致线程长时间阻塞。线程池具有最大线程数,因此大量阻塞的线程池线程可能会阻止任务启动。

        • 您需要将线程放入单线程单元中。所有 ThreadPool 线程都在多线程单元中。

        • 您需要有一个与线程相关联的稳定身份,或者将线程专用于某项任务。

        一个很大的区别是线程池线程上未处理的异常会终止进程;除了这三个例外:

        • ThreadAbortException 被抛出到线程池线程中,因为调用了 Abort

        • AppDomainUnloadedException 在线程池线程中被抛出,因为正在卸载应用程序域。

        • 公共语言运行时或宿主进程终止线程。

        一些很好的参考资料是:

        The Managed Thread Pool

        Threading in C#

        Programming the Thread Pool in the .NET Framework

        更新:响应 cmets。您可以使用GetAvailableThreads 方法来确定在任何给定时间线程池中的实际线程数。 ThreadPool.GetMaxThreads 是不同的数量。它是请求排队之前池中允许的最大值,而不是当前池中的实际线程数。

        【讨论】:

        • 根据文档,池默认为每个处理器维护 250 个工作线程。
        • 如果你想确保你的线程在应用程序关闭之前完成它的工作,一些长时间运行的任务可能需要将背景属性设置为 false(当然这并不能保证它会但至少它会正常情况下不会关闭)
        • @Fredrik Mörk:这听起来像是一个错字。每个核心 25 个
        • @Mitch:我刚刚通过调用 ThreadPool.GetMaxThreads 进行了检查,它返回 500(在双核机器上)。
        • @Mitch Wheat @Josh 不是类型,数量因框架版本而异
        【解决方案4】:

        不同之处不在于线程本身,因为它们的行为相同,不同之处在于谁管理线程的生命周期以及您如何使用它们。

        .net 中的线程池是一个会增长或收缩的线程池,当您排队等待线程池处理时,它将决定是否需要启动新线程或重用现有线程。您不必显式创建线程。

        这很好,但缺点是线程池中可用的线程数量有限,因此如果您将长时间运行的任务排队,这可能会对您的应用程序产生负面影响,因为您可能会用完线程池其他东西可能想要使用的线程。

        看这个article关于线程池

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-29
          • 1970-01-01
          • 1970-01-01
          • 2019-12-29
          • 1970-01-01
          • 2018-05-21
          • 2010-09-17
          相关资源
          最近更新 更多