【问题标题】:What is the advantage of creating a thread outside threadpool?在线程池之外创建线程有什么好处?
【发布时间】:2015-09-02 11:53:58
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net multithreading asynchronous task


    【解决方案1】:

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

    线程池,顾名思义,是一个线程池,它被分配一次并在整个过程中重复使用,以节省分配线程所需的时间和资源。池本身会根据需要重新调整大小。如果您排队的工作比池中实际存在的工作线程多,它将以 500 毫秒的间隔分配更多线程,一次一个(这样做是为了避免同时分配多个线程,而现有线程可能已经完成执行并可以为请求提供服务)。如果在线程池上执行许多长时间运行的操作,则会导致“线程饥饿”,这意味着委托将开始排队并仅在线程释放后才运行。这就是为什么您要避免大量线程对线程池线程进行长时间的工作。

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

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

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

    更多信息,请参见:

    【讨论】:

    • “线程池,顾名思义,是一个池线程。” - 哈哈哈
    【解决方案2】:

    “长时间运行”可以很好地量化,一个需要半秒以上的线程运行时间很长。这是现代机器上的处理器指令堆积如山,你必须每秒消耗 50 亿条指令。除非您将 Pi 的值计算到小数位数的数千位,否则很难以建设性的方式进行。

    实际线程只有在不燃烧核心但等待很多时才能花费这么长时间。总是在 I/O 完成时,例如从磁盘、网络、数据库服务器读取数据。这通常是您首先开始考虑使用线程的原因。

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

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

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

    请注意,在这个答案中听起来可能还不错。特别是 .NET 4.0 聘请了一位新经理,他在确定最佳运行线程数方面要聪明得多。它通过反馈循环来做到这一点,收集数据以发现活动线程是否真的完成了工作。并相应调整最佳值。这种方法的唯一问题是关闭反馈回路时常见的问题,您必须使其变慢,以免回路变得不稳定。换句话说,增加活动线程的数量并不是特别快。

    如果您提前知道线程非常糟糕,运行 很多 秒而没有真正的 cpu 负载,那么请始终选择 LongRunning。否则,这是一项调整工作,在程序完成后观察程序并对其进行修补以使其更优化。

    【讨论】:

      猜你喜欢
      • 2016-05-21
      • 2023-02-02
      • 1970-01-01
      • 2021-11-29
      • 2020-01-06
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多