【问题标题】:Should we use own threads or thread pool for small and frequent tasks?对于小而频繁的任务,我们应该使用自己的线程还是线程池?
【发布时间】:2012-03-08 22:29:27
【问题描述】:

在我的应用程序中,我有一组插件 - 当应用程序中发生某些事件时执行一些小动作的类。插件的每个方法都必须在单独的线程中调用,但每个插件只能同时运行一个方法。

我可以通过两种方式实现:

  1. 为每个插件创建一个线程,该线程将处理来自插件队列的事件,直到队列为空。然后休眠,直到新事件进入队列,处理它等等。

  2. 当事件到达插件的队列时,它在线程池线程中处理。当队列变为空时,将其释放回线程池。

问题是:两种方式的优缺点是什么?

一些说明:

  • 插件不会过多地加载 CPU,大部分时间它们只是等待下一个事件。
  • 我不在乎创建线程所需的时间,插件是长期存在的。
  • 通常每个应用程序都有大约 10-20 个这样的插件。

【问题讨论】:

  • “虽然每个插件只能同时运行一个方法” - 你的意思是对于给定的插件,你不能同时调用两个方法吗?但是如果你有单独的插件,你可以同时在这些不同的插件上执行方法吗?

标签: .net multithreading performance threadpool


【解决方案1】:

插件的每个方法都必须在单独的线程中调用,但每个插件只能同时运行一个方法。

如果这是您的要求,我会考虑围绕BlockingCollection<T> 构建插件。添加插件时,启动一个长时间运行的任务,该任务仅在 BlockingCollection.GetConsumingEnumerable() 上执行 foreach

这将允许您将项目添加到它们的“队列”中,并且插件将自动按顺序处理这些项目,而无需您自己的“睡眠”处理。每个插件都可以使用blockingCollection.GetConsumingEnumerable 来处理其队列中的项目。

【讨论】:

    【解决方案2】:

    我看到它是双向的。每个插件一个线程的丑陋之处在于——你开始依赖“只有一个线程接触我的插件”的想法,然后有人犯了一个错误,一个插件的线程去接触了另一个插件(尽管复杂的事件处理或类似的东西)。然后你会遇到非常难以追踪的比赛条件。

    @Reed-Copsey 建议的方法要干净得多,但是如果您必须使用您提到的两种方法之一,那么使用线程池并适当地锁定将在以后为您省去一些心痛。如果您有多个团队成员在项目的多个方面工作,这尤其适用。

    【讨论】:

      【解决方案3】:

      我会选择#2。原因是你没有保留一堆大部分时间空闲的线程。这样做确实没有缺点,因为您还可以获得不同插件之间的并行性以及每个给定插件的顺序执行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-28
        • 2012-06-24
        • 2012-10-29
        • 2011-07-09
        • 1970-01-01
        • 2014-09-02
        相关资源
        最近更新 更多