代码之家  ›  专栏  ›  技术社区  ›  Vaibhav

我什么时候不应该在.NET中使用threadpool?[关闭]

  •  37
  • Vaibhav  · 技术社区  · 17 年前

    我应该什么时候 在.NET中使用threadpool?

    看起来最好的选择是使用threadpool,在这种情况下,为什么它不是唯一的选择?

    你在这方面有什么经验?

    9 回复  |  直到 7 年前
        1
  •  17
  •   V0d01ey Tony Kiernan    7 年前

    我不使用的唯一原因是 ThreadPool 因为便宜的多线程是如果我需要…

    1. 与正在运行的方法中断(例如,杀死它)
    2. 在A上运行代码 STA thread (这发生在我身上)
    3. 在我的应用程序死后保持线程的活动状态( 线程池 线程是后台线程)
    4. 如果我需要更改线程的优先级。我们不能更改线程池中线程的优先级,这在默认情况下是正常的。

    附笔。: msdn文章 "The Managed Thread Pool" 包含标题为, “何时不使用线程池线程” ,其中列出了不使用线程池的可能原因,这些原因非常相似,但略为完整。

    有很多原因可以让你跳过 线程池 但是如果你不认识他们 线程池 对你来说应该足够好。

    或者,看看新的 Parallel Extensions Framework 里面有一些整洁的东西可以满足你的需要而不必使用 线程池 .

        2
  •  29
  •   Ian Boyd    12 年前

    @埃里克,我得同意迪恩的意见。线很贵。你不能假设你的程序是唯一运行的。当每个人都贪婪地使用资源时,问题就会成倍增加。

    我更喜欢手动创建线程并自己控制它们。它使代码非常容易理解。

    如果合适的话就可以了。但是,如果您需要大量的工作线程,您所做的就是使代码更加复杂。现在您必须编写代码来管理它们。如果您只是使用一个线程池,那么您将免费获得所有线程管理。语言提供的线程池很可能比您为自己滚动的线程池更健壮、更高效、更不麻烦。

    Thread t = new Thread(new ThreadStart(DoSomething));  
    t.Start();  
    t.Join();  
    

    我希望在正常情况下,您之间会有一些额外的代码 Start() Join() . 否则,额外的线程是无用的,而且您没有理由浪费资源。

    人们太害怕线程使用的资源了。我从未见过创建和启动一个线程需要超过一毫秒的时间。可以创建的线程数没有硬限制。RAM使用最少。一旦你有几百个线程,由于上下文切换,CPU就成了一个问题,因此在那一点上,你可能想对你的设计产生幻想。

    毫秒是 长的 现代硬件时代。在3GHz的机器上有300万次循环。而且,您不是唯一一个创建线程的人。你的线程和其他程序的线程争夺CPU。如果您使用的线程不太多,另一个程序也不太多,那么一起使用的线程太多了。

    说真的,不要让生活变得比需要的更复杂。不要使用线程池,除非您需要它提供的非常具体的东西。

    的确。不要让生活变得更复杂。如果你的程序需要多个工作线程,不要重新设计轮子。使用线程池。这就是为什么它在那里。你愿意上自己的弦乐课吗?

        3
  •  8
  •   Derek Park    17 年前

    只要您有工作线程的概念,线程池就有意义。任何时候您可以轻松地将处理划分为较小的作业(每个作业都可以独立处理),工作线程(因此是线程池)都是有意义的。

    当您需要执行完全不同和不相关操作的线程时,线程池没有意义,这些操作不能被视为“作业”;例如,一个线程用于GUI事件处理,另一个线程用于后端处理。当处理形成管道时,线程池也没有意义。

    基本上,如果您有启动、处理作业和退出的线程,那么线程池可能就是解决问题的方法。否则,线程池并不能真正起作用。

        4
  •  8
  •   Dogmang    17 年前

    为了反驳我的回答,我想补充一点,如果你需要保证你的线程会立即开始工作,最好不要使用线程池线程。每个AppDomain运行的线程池线程的最大数量是有限的,因此如果它们都很忙,您的工作可能需要等待。毕竟,它被称为“队列用户工作项”。

    当然,有两个注意事项:

    1. 您可以在运行时更改代码中线程池线程的最大数量,因此没有什么可以阻止您检查当前与最大数量的对比,并在需要时增加最大数量。
    2. 旋转一条新的线有它自己的时间惩罚-它是否值得你去打取决于你的情况。
        5
  •  2
  •   Will Dean    17 年前

    我不是只说 理论知识。我写 并维护大量应用程序 大量使用多线程, 我一般都找不到线索 池是正确的答案。

    啊,权威人士的观点——但要时刻注意那些可能加入Windows内核团队的人。

    我们两人都不同意这样一个事实:如果您有一些特定的需求,那么.NET线程池可能不是正确的。我们反对的是制造线程的机器成本的琐碎化。

    首先,为线程池创建线程的巨大开销。我不希望我的机器被错误地知道创建线程的费用的人编写的代码填满,例如,我不知道它会导致在每个附加到进程的DLL中调用一个方法(其中一些将由第三方创建),这可能会很好地激发一批代码,这些代码需要我根本不在RAM,几乎肯定不需要在L1。

    现代机器中内存层次结构的形状意味着“分散”CPU的注意力是你能做的最糟糕的事情,每个关心他们的工艺的人都应该努力避免它。

        6
  •  1
  •   Quibblesome    17 年前

    当你要执行一个需要很长时间的操作时,或者可能是一个连续的后台线程。 我想您总是可以增加池中可用线程的数量,但是对于一个永远不会返回池的线程来说,产生管理成本几乎没有意义。

        7
  •  0
  •   hwiechers    13 年前

    这里列出了一些原因:

    http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

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

    • 您需要一个前台线程。
    • 您需要一个线程具有特定的优先级。
    • 您的任务会导致线程长时间阻塞。线程池的线程数最多,因此 阻止的线程池线程数可能会阻止任务 启动。
    • 您需要将线程放入单线程单元。所有线程池线程都在多线程单元中。
    • 您需要有一个与线程相关联的稳定标识,或者将线程专用于任务。
        8
  •  0
  •   supercat    12 年前

    线程池线程适用于同时满足以下两个条件的任务:

    1. 这项任务不必花费大量的时间来等待事情的发生。
    2. 任何等待任务完成的事情都可能等待许多任务完成,因此其调度优先级不太可能对事情产生太大影响。

    使用线程池线程而不是创建新线程将节省大量但有限制的时间。如果与执行任务所需的时间相比,该时间很重要,则线程池任务可能是合适的。然而,执行任务所需的时间越长,使用线程池的好处越小,任务阻碍线程池效率的可能性越大。

        9
  •  -1
  •   Derek Park    17 年前

    @埃里克

    @德里克,我不完全同意你举的例子。如果你不知道你的机器上运行的是什么,也不知道你的应用程序在一定的负载下会使用多少线程、句柄、CPU时间、RAM等等,那么你就有麻烦了。

    你是你所写程序的唯一目标客户吗?如果不是,你就不能确定其中的大部分。通常,您不知道什么时候编写一个程序,它是否会有效地单独执行,或者它是否会运行在一个受到DDOS攻击的Web服务器上。你不知道你将有多少CPU时间。

    假设你的程序的行为是基于输入而改变的,那么你甚至很难确切知道你的程序将消耗多少内存或CPU时间。当然,您应该对程序的行为有一个很好的了解,但是大多数程序从来没有经过分析来确定到底要使用多少内存、多少句柄等,因为完整的分析是昂贵的。如果你不写实时软件,那么回报就不值得你这么做。

    总的来说,声称知道你的程序将如何运行是很牵强的,声称知道关于机器的一切都是荒谬的。

    老实说,如果您不知道应该使用什么方法:手动线程、线程池、委托,以及如何实现它来满足应用程序的需要,那么您就有麻烦了。

    我并不完全不同意,但我不知道这有什么关系。这个站点之所以出现在这里,是因为程序员并不总是有所有的答案。

    如果您的应用程序足够复杂,需要限制您使用的线程的数量,那么您是否总是想要比框架提供的更多的控制?

    不需要。如果我需要一个线程池,我将使用提供的线程池,除非并且直到我发现它不够用为止。我不会简单地假设所提供的线程池不足以满足我的需要,而不确认情况是否如此。

    我不是以一个只有理论知识的人的身份说话。我编写和维护大量使用多线程的大容量应用程序,通常我不认为线程池是正确的答案。

    我的大部分专业经验都是在多线程和多处理程序方面。我也经常需要推出自己的解决方案。这并不意味着线程池在很多情况下都不有用或不合适。线程池是为处理工作线程而构建的。在多个工作线程合适的情况下,提供的线程池通常应该是第一种方法。

    推荐文章