【问题标题】:Multi-Threading: At what point have you created too many threads?多线程:您在什么时候创建了太多线程?
【发布时间】:2009-08-17 00:58:59
【问题描述】:

我正在开发一个多线程应用程序。

此应用程序最初是单线程,后来扩展到多线程以实现性能提升。

我有一个主线程,它将工作分成更小的块并将其卸载到处理这些块的工作线程。这部分是使用信号量控制的,以在任何时候只允许 X 数量的工作线程。工作线程产生数据块,然后将其存储在队列或环形缓冲区中,然后由一个保存线程读取。该线程负责将数据块保存到磁盘(有时跨本地网络)。

我的开发机器是具有 8GB RAM 的四核。在我的机器上使用 3 个工作线程和 1 个保护线程运行应用程序会导致网络上稳定的数据流,处理器的平均利用率为 75%。

解决这个问题的第二种方法是在工作线程和保护线程之间添加另一组线程(即从当前工作线程中取出一个任务并将其添加到另一个线程)(我还添加了一个队列对于这些线程中的每一个)应用程序似乎没有在我的机器上获得任何速度,因为似乎对资源 RAM 总线饱和和处理器争用有太多争用。

通过对线程数量及其优先级的大量实验,我找到了适合我的机器的理想设置,无论是解决此问题的第一种方法还是第二种方法。现在生产机器将有 8 个内核和 64GB 的 RAM。必须为它配置一个非常不同的环境和应用程序。

我的问题是,您在什么时候创建了太多线程?确定给定机器的理想设置是否总是一个实验问题?是否有一种方法可以确定或观察锁定是否占用了应用程序太多的时间?

(我没有使用线程池,因为它不符合我的需要,因为长时间运行的线程由信号量和其他锁定机制管理。)

【问题讨论】:

    标签: .net multithreading


    【解决方案1】:

    当您的应用程序的整体性能下降或对在同一机器上运行的其他应用程序的影响受到负面影响到不可接受的程度时,您创建了太多线程。

    关键是没有绝对的答案。

    我一直在处理的一个应用程序使用 1000 个线程的线程池,对于我们正在做的事情,这似乎是正确的数字。在一种配置中,我们没有限制它,它达到了 30,000+,基本上使机器停止运转。

    您基本上必须对其进行性能测试,并拥有足够的监控/仪器来确定应用程序的整体吞吐量、资源使用情况、线程利用率,并了解空闲线程的情况以及等待队列中等待提取的工作多长时间。然后根据需要进行调整。

    一个警告:在添加另一层线程之前要仔细考虑。我相信你知道,编写多线程代码很困难。尽量保持简单。添加另一层是一个冒险的步骤。

    【讨论】:

    • +1 爬山方法似乎是解决这个问题最可靠的方法之一
    【解决方案2】:

    没有人可以给你一个简单的数字答案,因为它太依赖了,不仅取决于机器有多少核心和c,而且还取决于机器应该与你同时执行的其他任务(如果有的话)应用程序,以及您的线程到底在做什么。

    举一个后一个问题的例子:我曾经有一个非常简单的“爬虫”,其中一定数量的线程专门用于我确定需要的 HTTP GET 页面——每个线程大部分时间都被阻塞在用于执行 HTTP GET 的套接字调用,因此为了获得相当好的性能,我需要大量的它们(数百个)。后来我切换了底层方法以使用异步网络 I/O 而不是阻塞套接字——突然之间,每个线程都可以轻松地拥有数百个“正在运行”的 URL,因此有数百个这样的线程处于活动状态会使系统不堪重负,可能导致打开的套接字数量超过系统可以处理的数量(它不是一个非常大或配置不高的服务器!-)导致崩溃,或者至少由于过度交换等导致严重的减速。

    因此,即使对于完全 I/O 绑定的线程,它们使用的 I/O 的确切形式(例如阻塞或异步)也会对线程数(或进程或任何其他类似的线程)产生巨大影响单位)对于某个整体软件任务是最优的。显然,必须根据内核的可用性和内核可以在其中工作的 RAM 以及其他资源(例如,如果您的某些线程能够使用可用的一些线程GPU 或其他专用处理单元来委派他们的一些工作)。

    最后,一旦你知道所有这些参数,你就可以做出一个合理的大致估计,但你可能会偏离一个很大的因素——因此,在实际工作负载上进行基准测试,(比如说)一半,两倍很多,你猜想的线程应该是最优的,这是在部署的性能调整后期阶段花费一些时间和资源的好方法。一般而言,即使对于非常有经验的架构师、开发人员和系统管理员来说,性能行为也常常令人惊讶,因此实际基准、仔细测量和相应调整的经验数据驱动方法没有真正好的替代品。 (请注意,盲目经验主义 - 只是试图适应实验观察而没有任何合理的模型来理解它们 - 几乎与忽略数据的教条和教义方法一样糟糕,但是,这是另一个咆哮;-)。

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多